mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-20 12:09:45 +01:00
Improve reconnections & Avatar handling
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
9fff869d9a
commit
6e68f41d1f
@ -73,6 +73,7 @@ import com.nextcloud.talk.utils.database.user.UserUtils;
|
|||||||
import com.nextcloud.talk.utils.power.PowerManagerUtils;
|
import com.nextcloud.talk.utils.power.PowerManagerUtils;
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
||||||
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder;
|
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder;
|
||||||
|
import com.nextcloud.talk.utils.singletons.MerlinTheWizard;
|
||||||
import com.nextcloud.talk.webrtc.*;
|
import com.nextcloud.talk.webrtc.*;
|
||||||
import com.wooplr.spotlight.SpotlightView;
|
import com.wooplr.spotlight.SpotlightView;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
@ -88,6 +89,7 @@ import org.apache.commons.lang3.StringEscapeUtils;
|
|||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
import org.parceler.Parcel;
|
||||||
import org.webrtc.*;
|
import org.webrtc.*;
|
||||||
import pub.devrel.easypermissions.AfterPermissionGranted;
|
import pub.devrel.easypermissions.AfterPermissionGranted;
|
||||||
|
|
||||||
@ -165,7 +167,7 @@ public class CallController extends BaseController {
|
|||||||
private VideoCapturer videoCapturer;
|
private VideoCapturer videoCapturer;
|
||||||
private EglBase rootEglBase;
|
private EglBase rootEglBase;
|
||||||
private boolean leavingCall = false;
|
private boolean leavingCall = false;
|
||||||
private boolean inCall = false;
|
private boolean connectedToCall = false;
|
||||||
private Disposable signalingDisposable;
|
private Disposable signalingDisposable;
|
||||||
private Disposable pingDisposable;
|
private Disposable pingDisposable;
|
||||||
private List<PeerConnection.IceServer> iceServers;
|
private List<PeerConnection.IceServer> iceServers;
|
||||||
@ -207,6 +209,15 @@ public class CallController extends BaseController {
|
|||||||
|
|
||||||
private PowerManagerUtils powerManagerUtils;
|
private PowerManagerUtils powerManagerUtils;
|
||||||
|
|
||||||
|
private Handler handler;
|
||||||
|
|
||||||
|
private CallStatus currentCallStatus;
|
||||||
|
|
||||||
|
@Parcel
|
||||||
|
public enum CallStatus {
|
||||||
|
CALLING, CALLING_TIMEOUT, ESTABLISHED, RECONNECTING, OFFLINE
|
||||||
|
}
|
||||||
|
|
||||||
public CallController(Bundle args) {
|
public CallController(Bundle args) {
|
||||||
super(args);
|
super(args);
|
||||||
NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
|
NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
|
||||||
@ -227,6 +238,7 @@ public class CallController extends BaseController {
|
|||||||
|
|
||||||
isFromNotification = TextUtils.isEmpty(roomToken);
|
isFromNotification = TextUtils.isEmpty(roomToken);
|
||||||
powerManagerUtils = new PowerManagerUtils();
|
powerManagerUtils = new PowerManagerUtils();
|
||||||
|
currentCallStatus = CallStatus.CALLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -273,13 +285,9 @@ public class CallController extends BaseController {
|
|||||||
|
|
||||||
callControls.setZ(100.0f);
|
callControls.setZ(100.0f);
|
||||||
basicInitialization();
|
basicInitialization();
|
||||||
|
|
||||||
if (isFromNotification) {
|
|
||||||
handleFromNotification();
|
|
||||||
} else {
|
|
||||||
initViews();
|
initViews();
|
||||||
checkPermissions();
|
|
||||||
}
|
initiateCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void basicInitialization() {
|
private void basicInitialization() {
|
||||||
@ -357,7 +365,6 @@ public class CallController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initViews();
|
|
||||||
checkPermissions();
|
checkPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,7 +434,7 @@ public class CallController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inCall) {
|
if (!connectedToCall) {
|
||||||
fetchSignalingSettings();
|
fetchSignalingSettings();
|
||||||
}
|
}
|
||||||
} else if (getActivity() != null && EffortlessPermissions.somePermissionPermanentlyDenied(getActivity(),
|
} else if (getActivity() != null && EffortlessPermissions.somePermissionPermanentlyDenied(getActivity(),
|
||||||
@ -466,7 +473,7 @@ public class CallController extends BaseController {
|
|||||||
microphoneControlButton.getHierarchy().setPlaceholderImage(R.drawable.ic_mic_off_white_24px);
|
microphoneControlButton.getHierarchy().setPlaceholderImage(R.drawable.ic_mic_off_white_24px);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inCall) {
|
if (!connectedToCall) {
|
||||||
fetchSignalingSettings();
|
fetchSignalingSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -484,7 +491,7 @@ public class CallController extends BaseController {
|
|||||||
if (getActivity() != null && (EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_CAMERA) ||
|
if (getActivity() != null && (EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_CAMERA) ||
|
||||||
EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_MICROPHONE))) {
|
EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_MICROPHONE))) {
|
||||||
checkIfSomeAreApproved();
|
checkIfSomeAreApproved();
|
||||||
} else if (!inCall) {
|
} else if (!connectedToCall) {
|
||||||
fetchSignalingSettings();
|
fetchSignalingSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,7 +641,7 @@ public class CallController extends BaseController {
|
|||||||
toggleMedia(true, false);
|
toggleMedia(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isVoiceOnlyCall && !inCall) {
|
if (isVoiceOnlyCall && !connectedToCall) {
|
||||||
fetchSignalingSettings();
|
fetchSignalingSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,7 +663,7 @@ public class CallController extends BaseController {
|
|||||||
|
|
||||||
@OnClick(R.id.callControlHangupView)
|
@OnClick(R.id.callControlHangupView)
|
||||||
void onHangupClick() {
|
void onHangupClick() {
|
||||||
hangup(false);
|
hangup(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.call_control_camera)
|
@OnClick(R.id.call_control_camera)
|
||||||
@ -751,7 +758,7 @@ public class CallController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inCall) {
|
if (connectedToCall) {
|
||||||
if (!hasMCU) {
|
if (!hasMCU) {
|
||||||
for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) {
|
for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) {
|
||||||
magicPeerConnectionWrapperList.get(i).sendChannelData(new DataChannelMessage(message));
|
magicPeerConnectionWrapperList.get(i).sendChannelData(new DataChannelMessage(message));
|
||||||
@ -1056,7 +1063,8 @@ public class CallController extends BaseController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNext(GenericOverall genericOverall) {
|
public void onNext(GenericOverall genericOverall) {
|
||||||
inCall = true;
|
connectedToCall = true;
|
||||||
|
currentCallStatus = CallStatus.CALLING;
|
||||||
|
|
||||||
if (connectingView != null) {
|
if (connectingView != null) {
|
||||||
connectingView.setVisibility(View.GONE);
|
connectingView.setVisibility(View.GONE);
|
||||||
@ -1077,8 +1085,8 @@ public class CallController extends BaseController {
|
|||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.repeatWhen(observable -> observable.delay(5000, TimeUnit.MILLISECONDS))
|
.repeatWhen(observable -> observable.delay(5000, TimeUnit.MILLISECONDS))
|
||||||
.takeWhile(observable -> inCall)
|
.takeWhile(observable -> connectedToCall)
|
||||||
.retry(3, observable -> inCall)
|
.retry(3, observable -> connectedToCall)
|
||||||
.subscribe(new Observer<GenericOverall>() {
|
.subscribe(new Observer<GenericOverall>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(Disposable d) {
|
public void onSubscribe(Disposable d) {
|
||||||
@ -1119,8 +1127,8 @@ public class CallController extends BaseController {
|
|||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.repeatWhen(observable -> observable)
|
.repeatWhen(observable -> observable)
|
||||||
.takeWhile(observable -> inCall)
|
.takeWhile(observable -> connectedToCall)
|
||||||
.retry(3, observable -> inCall)
|
.retry(3, observable -> connectedToCall)
|
||||||
.subscribe(new Observer<SignalingOverall>() {
|
.subscribe(new Observer<SignalingOverall>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(Disposable d) {
|
public void onSubscribe(Disposable d) {
|
||||||
@ -1177,11 +1185,24 @@ public class CallController extends BaseController {
|
|||||||
joinRoomAndCall();
|
joinRoomAndCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initiateCall() {
|
||||||
|
if (!TextUtils.isEmpty(roomToken)) {
|
||||||
|
checkPermissions();
|
||||||
|
} else {
|
||||||
|
handleFromNotification();
|
||||||
|
}
|
||||||
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
public void onMessageEvent(WebSocketCommunicationEvent webSocketCommunicationEvent) {
|
public void onMessageEvent(WebSocketCommunicationEvent webSocketCommunicationEvent) {
|
||||||
switch (webSocketCommunicationEvent.getType()) {
|
switch (webSocketCommunicationEvent.getType()) {
|
||||||
case "hello":
|
case "hello":
|
||||||
joinRoomAndCall();
|
if (!currentCallStatus.equals(CallStatus.RECONNECTING)) {
|
||||||
|
if (!webSocketCommunicationEvent.getHashMap().containsKey("oldResumeId")) {
|
||||||
|
initiateCall();
|
||||||
|
} else {
|
||||||
|
// do nothing, let's just continue
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "roomJoined":
|
case "roomJoined":
|
||||||
if (hasExternalSignalingServer) {
|
if (hasExternalSignalingServer) {
|
||||||
@ -1300,11 +1321,12 @@ public class CallController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hangup(boolean dueToNetworkChange) {
|
private void hangup(boolean shutDownView) {
|
||||||
|
|
||||||
leavingCall = true;
|
leavingCall = true;
|
||||||
inCall = false;
|
connectedToCall = false;
|
||||||
|
|
||||||
|
if (shutDownView) {
|
||||||
if (videoCapturer != null) {
|
if (videoCapturer != null) {
|
||||||
try {
|
try {
|
||||||
videoCapturer.stopCapture();
|
videoCapturer.stopCapture();
|
||||||
@ -1315,11 +1337,6 @@ public class CallController extends BaseController {
|
|||||||
videoCapturer = null;
|
videoCapturer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) {
|
|
||||||
endPeerConnection(magicPeerConnectionWrapperList.get(i).getSessionId(), false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pipVideoView != null) {
|
if (pipVideoView != null) {
|
||||||
pipVideoView.release();
|
pipVideoView.release();
|
||||||
}
|
}
|
||||||
@ -1350,17 +1367,17 @@ public class CallController extends BaseController {
|
|||||||
if (TextUtils.isEmpty(credentials) && hasExternalSignalingServer) {
|
if (TextUtils.isEmpty(credentials) && hasExternalSignalingServer) {
|
||||||
WebSocketConnectionHelper.deleteExternalSignalingInstanceForUserEntity(-1);
|
WebSocketConnectionHelper.deleteExternalSignalingInstanceForUserEntity(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dueToNetworkChange) {
|
|
||||||
hangupNetworkCalls();
|
|
||||||
} else {
|
|
||||||
if (getActivity() != null) {
|
|
||||||
getActivity().finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hangupNetworkCalls() {
|
for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) {
|
||||||
|
endPeerConnection(magicPeerConnectionWrapperList.get(i).getSessionId(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
hangupNetworkCalls(shutDownView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hangupNetworkCalls(boolean shutDownView) {
|
||||||
|
if (MerlinTheWizard.isConnectedToInternet()) {
|
||||||
ncApi.leaveCall(credentials, ApiUtils.getUrlForCall(baseUrl, roomToken))
|
ncApi.leaveCall(credentials, ApiUtils.getUrlForCall(baseUrl, roomToken))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
@ -1372,16 +1389,18 @@ public class CallController extends BaseController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNext(GenericOverall genericOverall) {
|
public void onNext(GenericOverall genericOverall) {
|
||||||
if (hasExternalSignalingServer) {
|
if (!TextUtils.isEmpty(credentials) && hasExternalSignalingServer) {
|
||||||
webSocketClient.joinRoomWithRoomTokenAndSession("", callSession);
|
webSocketClient.joinRoomWithRoomTokenAndSession("", callSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMultiSession) {
|
if (isMultiSession) {
|
||||||
if (getActivity() != null) {
|
if (shutDownView && getActivity() != null) {
|
||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
|
} else if (!shutDownView && currentCallStatus.equals(CallStatus.RECONNECTING)) {
|
||||||
|
initiateCall();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
leaveRoom();
|
leaveRoom(shutDownView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,9 +1414,12 @@ public class CallController extends BaseController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (shutDownView && getActivity() != null) {
|
||||||
|
getActivity().finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void leaveRoom() {
|
private void leaveRoom(boolean shutDownView) {
|
||||||
ncApi.leaveRoom(credentials, ApiUtils.getUrlForSettingMyselfAsActiveParticipant(baseUrl, roomToken))
|
ncApi.leaveRoom(credentials, ApiUtils.getUrlForSettingMyselfAsActiveParticipant(baseUrl, roomToken))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
@ -1409,7 +1431,7 @@ public class CallController extends BaseController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNext(GenericOverall genericOverall) {
|
public void onNext(GenericOverall genericOverall) {
|
||||||
if (getActivity() != null) {
|
if (shutDownView && getActivity() != null) {
|
||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1633,6 +1655,7 @@ public class CallController extends BaseController {
|
|||||||
pipVideoView.setLayoutParams(layoutParams);
|
pipVideoView.setLayoutParams(layoutParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
public void onMessageEvent(PeerConnectionEvent peerConnectionEvent) {
|
public void onMessageEvent(PeerConnectionEvent peerConnectionEvent) {
|
||||||
if (peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent.PeerConnectionEventType
|
if (peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent.PeerConnectionEventType
|
||||||
@ -1647,7 +1670,7 @@ public class CallController extends BaseController {
|
|||||||
boolean enableVideo = peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent
|
boolean enableVideo = peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent
|
||||||
.PeerConnectionEventType.SENSOR_FAR) && videoOn;
|
.PeerConnectionEventType.SENSOR_FAR) && videoOn;
|
||||||
if (getActivity() != null && EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_CAMERA) &&
|
if (getActivity() != null && EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_CAMERA) &&
|
||||||
inCall && videoOn
|
connectedToCall && videoOn
|
||||||
&& enableVideo != localVideoTrack.enabled()) {
|
&& enableVideo != localVideoTrack.enabled()) {
|
||||||
toggleMedia(enableVideo, true);
|
toggleMedia(enableVideo, true);
|
||||||
}
|
}
|
||||||
@ -1678,7 +1701,7 @@ public class CallController extends BaseController {
|
|||||||
int finalI = i;
|
int finalI = i;
|
||||||
Observable
|
Observable
|
||||||
.interval(1, TimeUnit.SECONDS)
|
.interval(1, TimeUnit.SECONDS)
|
||||||
.takeWhile(observer -> inCall)
|
.takeWhile(observer -> connectedToCall)
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.doOnNext(n -> magicPeerConnectionWrapperList.get(finalI).sendChannelData(dataChannelMessage));
|
.doOnNext(n -> magicPeerConnectionWrapperList.get(finalI).sendChannelData(dataChannelMessage));
|
||||||
break;
|
break;
|
||||||
@ -1796,14 +1819,23 @@ public class CallController extends BaseController {
|
|||||||
if (relativeLayout != null) {
|
if (relativeLayout != null) {
|
||||||
SimpleDraweeView avatarImageView = relativeLayout.findViewById(R.id.avatarImageView);
|
SimpleDraweeView avatarImageView = relativeLayout.findViewById(R.id.avatarImageView);
|
||||||
|
|
||||||
if (participantMap.containsKey(session) && avatarImageView.getDrawable() == null) {
|
String userId;
|
||||||
|
|
||||||
|
if (hasMCU) {
|
||||||
|
userId = webSocketClient.getUserIdForSession(session);
|
||||||
|
} else {
|
||||||
|
userId = participantMap.get(session).getUserId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(userId)) {
|
||||||
|
|
||||||
if (getActivity() != null) {
|
if (getActivity() != null) {
|
||||||
|
avatarImageView.setController(null);
|
||||||
|
|
||||||
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
|
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
|
||||||
.setOldController(avatarImageView.getController())
|
.setOldController(avatarImageView.getController())
|
||||||
.setAutoPlayAnimations(true)
|
|
||||||
.setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(baseUrl,
|
.setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(baseUrl,
|
||||||
participantMap.get(session).getUserId(),
|
userId,
|
||||||
R.dimen.avatar_size_big), null))
|
R.dimen.avatar_size_big), null))
|
||||||
.build();
|
.build();
|
||||||
avatarImageView.setController(draweeController);
|
avatarImageView.setController(draweeController);
|
||||||
@ -1958,4 +1990,24 @@ public class CallController extends BaseController {
|
|||||||
showCallControls();
|
showCallControls();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
|
public void onMessageEvent(NetworkEvent networkEvent) {
|
||||||
|
if (networkEvent.getNetworkConnectionEvent().equals(NetworkEvent.NetworkConnectionEvent.NETWORK_CONNECTED)) {
|
||||||
|
if (handler != null) {
|
||||||
|
handler.removeCallbacksAndMessages(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentCallStatus = CallStatus.RECONNECTING;
|
||||||
|
hangupNetworkCalls(false);
|
||||||
|
|
||||||
|
} else if (networkEvent.getNetworkConnectionEvent().equals(NetworkEvent.NetworkConnectionEvent.NETWORK_DISCONNECTED)) {
|
||||||
|
if (handler != null) {
|
||||||
|
handler.removeCallbacksAndMessages(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentCallStatus = CallStatus.OFFLINE;
|
||||||
|
hangup(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ import javax.inject.Inject;
|
|||||||
@AutoInjector(NextcloudTalkApplication.class)
|
@AutoInjector(NextcloudTalkApplication.class)
|
||||||
public class MerlinTheWizard {
|
public class MerlinTheWizard {
|
||||||
private static Merlin merlin;
|
private static Merlin merlin;
|
||||||
private static MerlinsBeard merlinsBeard;
|
|
||||||
|
|
||||||
private UserEntity currentUserEntity;
|
private UserEntity currentUserEntity;
|
||||||
|
|
||||||
@ -47,10 +46,16 @@ public class MerlinTheWizard {
|
|||||||
@Inject
|
@Inject
|
||||||
UserUtils userUtils;
|
UserUtils userUtils;
|
||||||
|
|
||||||
|
private static boolean isConnectedToInternet;
|
||||||
|
|
||||||
public MerlinTheWizard() {
|
public MerlinTheWizard() {
|
||||||
NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
|
NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isConnectedToInternet() {
|
||||||
|
return isConnectedToInternet;
|
||||||
|
}
|
||||||
|
|
||||||
public void initMerlin() {
|
public void initMerlin() {
|
||||||
if (userUtils.anyUserExists() && (currentUserEntity == null ||
|
if (userUtils.anyUserExists() && (currentUserEntity == null ||
|
||||||
(userUtils.getCurrentUser().getId() != currentUserEntity.getId()))) {
|
(userUtils.getCurrentUser().getId() != currentUserEntity.getId()))) {
|
||||||
@ -60,14 +65,13 @@ public class MerlinTheWizard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Merlin getMerlin() {
|
public Merlin getMerlin() {
|
||||||
|
if (merlin == null) {
|
||||||
|
initMerlin();
|
||||||
|
}
|
||||||
|
|
||||||
return merlin;
|
return merlin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MerlinsBeard getMerlinsBeard() {
|
|
||||||
return merlinsBeard;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void setupMerlinForCurrentUserEntity() {
|
private void setupMerlinForCurrentUserEntity() {
|
||||||
Endpoint endpoint = Endpoint.from(currentUserEntity.getBaseUrl() + "/index.php/204");
|
Endpoint endpoint = Endpoint.from(currentUserEntity.getBaseUrl() + "/index.php/204");
|
||||||
ResponseCodeValidator responseCodeValidator =
|
ResponseCodeValidator responseCodeValidator =
|
||||||
@ -81,12 +85,10 @@ public class MerlinTheWizard {
|
|||||||
|
|
||||||
merlin.bind();
|
merlin.bind();
|
||||||
|
|
||||||
merlinsBeard = new MerlinsBeard.Builder().withEndpoint(Endpoint.from(currentUserEntity.getBaseUrl() +
|
|
||||||
"/index.php/204")).withResponseCodeValidator(new ResponseCodeValidator.CaptivePortalResponseCodeValidator()).build(context);
|
|
||||||
|
|
||||||
merlin.registerConnectable(new Connectable() {
|
merlin.registerConnectable(new Connectable() {
|
||||||
@Override
|
@Override
|
||||||
public void onConnect() {
|
public void onConnect() {
|
||||||
|
isConnectedToInternet = true;
|
||||||
eventBus.post(new NetworkEvent(NetworkEvent.NetworkConnectionEvent.NETWORK_CONNECTED));
|
eventBus.post(new NetworkEvent(NetworkEvent.NetworkConnectionEvent.NETWORK_CONNECTED));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -94,6 +96,7 @@ public class MerlinTheWizard {
|
|||||||
merlin.registerDisconnectable(new Disconnectable() {
|
merlin.registerDisconnectable(new Disconnectable() {
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnect() {
|
public void onDisconnect() {
|
||||||
|
isConnectedToInternet = false;
|
||||||
eventBus.post(new NetworkEvent(NetworkEvent.NetworkConnectionEvent.NETWORK_DISCONNECTED));
|
eventBus.post(new NetworkEvent(NetworkEvent.NetworkConnectionEvent.NETWORK_DISCONNECTED));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -36,6 +36,7 @@ import com.nextcloud.talk.events.WebSocketCommunicationEvent;
|
|||||||
import com.nextcloud.talk.models.json.signaling.DataChannelMessage;
|
import com.nextcloud.talk.models.json.signaling.DataChannelMessage;
|
||||||
import com.nextcloud.talk.models.json.signaling.NCIceCandidate;
|
import com.nextcloud.talk.models.json.signaling.NCIceCandidate;
|
||||||
import com.nextcloud.talk.utils.LoggingUtils;
|
import com.nextcloud.talk.utils.LoggingUtils;
|
||||||
|
import com.nextcloud.talk.utils.singletons.MerlinTheWizard;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.webrtc.*;
|
import org.webrtc.*;
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ public class MagicPeerConnectionWrapper {
|
|||||||
private PeerConnection peerConnection;
|
private PeerConnection peerConnection;
|
||||||
private String sessionId;
|
private String sessionId;
|
||||||
private String nick;
|
private String nick;
|
||||||
private MediaConstraints mediaConstraints;
|
private MediaConstraints sdpConstraints;
|
||||||
private DataChannel magicDataChannel;
|
private DataChannel magicDataChannel;
|
||||||
private MagicSdpObserver magicSdpObserver;
|
private MagicSdpObserver magicSdpObserver;
|
||||||
private MediaStream remoteMediaStream;
|
private MediaStream remoteMediaStream;
|
||||||
@ -65,14 +66,17 @@ public class MagicPeerConnectionWrapper {
|
|||||||
|
|
||||||
private MediaStream localMediaStream;
|
private MediaStream localMediaStream;
|
||||||
private boolean isMCUPublisher;
|
private boolean isMCUPublisher;
|
||||||
|
private boolean hasMCU;
|
||||||
private String videoStreamType;
|
private String videoStreamType;
|
||||||
|
|
||||||
|
private int connectionAttempts = 0;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
public MagicPeerConnectionWrapper(PeerConnectionFactory peerConnectionFactory,
|
public MagicPeerConnectionWrapper(PeerConnectionFactory peerConnectionFactory,
|
||||||
List<PeerConnection.IceServer> iceServerList,
|
List<PeerConnection.IceServer> iceServerList,
|
||||||
MediaConstraints mediaConstraints,
|
MediaConstraints sdpConstraints,
|
||||||
String sessionId, String localSession, @Nullable MediaStream mediaStream,
|
String sessionId, String localSession, @Nullable MediaStream mediaStream,
|
||||||
boolean isMCUPublisher, boolean hasMCU, String videoStreamType) {
|
boolean isMCUPublisher, boolean hasMCU, String videoStreamType) {
|
||||||
|
|
||||||
@ -80,15 +84,16 @@ public class MagicPeerConnectionWrapper {
|
|||||||
|
|
||||||
this.localMediaStream = mediaStream;
|
this.localMediaStream = mediaStream;
|
||||||
this.videoStreamType = videoStreamType;
|
this.videoStreamType = videoStreamType;
|
||||||
|
this.hasMCU = hasMCU;
|
||||||
|
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
this.mediaConstraints = mediaConstraints;
|
this.sdpConstraints = sdpConstraints;
|
||||||
|
|
||||||
magicSdpObserver = new MagicSdpObserver();
|
magicSdpObserver = new MagicSdpObserver();
|
||||||
hasInitiated = sessionId.compareTo(localSession) < 0;
|
hasInitiated = sessionId.compareTo(localSession) < 0;
|
||||||
this.isMCUPublisher = isMCUPublisher;
|
this.isMCUPublisher = isMCUPublisher;
|
||||||
|
|
||||||
peerConnection = peerConnectionFactory.createPeerConnection(iceServerList, mediaConstraints,
|
peerConnection = peerConnectionFactory.createPeerConnection(iceServerList, sdpConstraints,
|
||||||
new MagicPeerConnectionObserver());
|
new MagicPeerConnectionObserver());
|
||||||
|
|
||||||
if (peerConnection != null) {
|
if (peerConnection != null) {
|
||||||
@ -102,13 +107,13 @@ public class MagicPeerConnectionWrapper {
|
|||||||
magicDataChannel = peerConnection.createDataChannel("status", init);
|
magicDataChannel = peerConnection.createDataChannel("status", init);
|
||||||
magicDataChannel.registerObserver(new MagicDataChannelObserver());
|
magicDataChannel.registerObserver(new MagicDataChannelObserver());
|
||||||
if (isMCUPublisher) {
|
if (isMCUPublisher) {
|
||||||
peerConnection.createOffer(magicSdpObserver, mediaConstraints);
|
peerConnection.createOffer(magicSdpObserver, sdpConstraints);
|
||||||
} else if (hasMCU) {
|
} else if (hasMCU) {
|
||||||
HashMap<String, String> hashMap = new HashMap<>();
|
HashMap<String, String> hashMap = new HashMap<>();
|
||||||
hashMap.put("sessionId", sessionId);
|
hashMap.put("sessionId", sessionId);
|
||||||
EventBus.getDefault().post(new WebSocketCommunicationEvent("peerReadyForRequestingOffer", hashMap));
|
EventBus.getDefault().post(new WebSocketCommunicationEvent("peerReadyForRequestingOffer", hashMap));
|
||||||
} else if (hasInitiated) {
|
} else if (hasInitiated) {
|
||||||
peerConnection.createOffer(magicSdpObserver, mediaConstraints);
|
peerConnection.createOffer(magicSdpObserver, sdpConstraints);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,6 +292,26 @@ public class MagicPeerConnectionWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void restartIce() {
|
||||||
|
if (connectionAttempts <= 5) {
|
||||||
|
if (!hasMCU || isMCUPublisher) {
|
||||||
|
MediaConstraints.KeyValuePair iceRestartConstraint =
|
||||||
|
new MediaConstraints.KeyValuePair("IceRestart", "true");
|
||||||
|
|
||||||
|
if (sdpConstraints.mandatory.contains(iceRestartConstraint)) {
|
||||||
|
sdpConstraints.mandatory.add(iceRestartConstraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
peerConnection.createOffer(magicSdpObserver, sdpConstraints);
|
||||||
|
} else {
|
||||||
|
// we have an MCU and this is not the publisher
|
||||||
|
// Do something if we have an MCU
|
||||||
|
}
|
||||||
|
|
||||||
|
connectionAttempts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class MagicPeerConnectionObserver implements PeerConnection.Observer {
|
private class MagicPeerConnectionObserver implements PeerConnection.Observer {
|
||||||
private final String TAG = "MagicPeerConnectionObserver";
|
private final String TAG = "MagicPeerConnectionObserver";
|
||||||
|
|
||||||
@ -300,6 +325,7 @@ public class MagicPeerConnectionWrapper {
|
|||||||
"iceConnectionChangeTo: " + iceConnectionState.name() + " over " + peerConnection.hashCode() + " " + sessionId);
|
"iceConnectionChangeTo: " + iceConnectionState.name() + " over " + peerConnection.hashCode() + " " + sessionId);
|
||||||
|
|
||||||
if (iceConnectionState.equals(PeerConnection.IceConnectionState.CONNECTED)) {
|
if (iceConnectionState.equals(PeerConnection.IceConnectionState.CONNECTED)) {
|
||||||
|
connectionAttempts = 0;
|
||||||
/*EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
/*EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
||||||
.PEER_CONNECTED, sessionId, null, null));*/
|
.PEER_CONNECTED, sessionId, null, null));*/
|
||||||
|
|
||||||
@ -314,6 +340,11 @@ public class MagicPeerConnectionWrapper {
|
|||||||
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.CLOSED)) {
|
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.CLOSED)) {
|
||||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
||||||
.PEER_CLOSED, sessionId, null, null, videoStreamType));
|
.PEER_CLOSED, sessionId, null, null, videoStreamType));
|
||||||
|
connectionAttempts = 0;
|
||||||
|
} else if (iceConnectionState.equals(PeerConnection.IceConnectionState.FAILED)) {
|
||||||
|
if (MerlinTheWizard.isConnectedToInternet() && connectionAttempts < 5) {
|
||||||
|
restartIce();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,7 +444,7 @@ public class MagicPeerConnectionWrapper {
|
|||||||
public void onSetSuccess() {
|
public void onSetSuccess() {
|
||||||
if (peerConnection != null) {
|
if (peerConnection != null) {
|
||||||
if (peerConnection.getLocalDescription() == null) {
|
if (peerConnection.getLocalDescription() == null) {
|
||||||
peerConnection.createAnswer(magicSdpObserver, mediaConstraints);
|
peerConnection.createAnswer(magicSdpObserver, sdpConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peerConnection.getRemoteDescription() != null) {
|
if (peerConnection.getRemoteDescription() != null) {
|
||||||
|
@ -30,15 +30,13 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
|
|||||||
import com.nextcloud.talk.events.NetworkEvent;
|
import com.nextcloud.talk.events.NetworkEvent;
|
||||||
import com.nextcloud.talk.events.WebSocketCommunicationEvent;
|
import com.nextcloud.talk.events.WebSocketCommunicationEvent;
|
||||||
import com.nextcloud.talk.models.database.UserEntity;
|
import com.nextcloud.talk.models.database.UserEntity;
|
||||||
|
import com.nextcloud.talk.models.json.participants.Participant;
|
||||||
import com.nextcloud.talk.models.json.signaling.NCMessageWrapper;
|
import com.nextcloud.talk.models.json.signaling.NCMessageWrapper;
|
||||||
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.*;
|
import com.nextcloud.talk.models.json.websocket.*;
|
||||||
import com.nextcloud.talk.utils.LoggingUtils;
|
import com.nextcloud.talk.utils.LoggingUtils;
|
||||||
import com.nextcloud.talk.utils.MagicMap;
|
import com.nextcloud.talk.utils.MagicMap;
|
||||||
import com.nextcloud.talk.utils.singletons.MerlinTheWizard;
|
import com.nextcloud.talk.utils.singletons.MerlinTheWizard;
|
||||||
import com.novoda.merlin.Endpoint;
|
|
||||||
import com.novoda.merlin.MerlinsBeard;
|
|
||||||
import com.novoda.merlin.ResponseCodeValidator;
|
|
||||||
import okhttp3.*;
|
import okhttp3.*;
|
||||||
import okio.ByteString;
|
import okio.ByteString;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
@ -80,10 +78,8 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
private int restartCount = 0;
|
private int restartCount = 0;
|
||||||
private boolean reconnecting = false;
|
private boolean reconnecting = false;
|
||||||
|
|
||||||
private HashMap<String, String> displayNameHashMap;
|
private HashMap<String, Participant> usersHashMap;
|
||||||
private HashMap<String, String> userIdSesssionHashMap;
|
|
||||||
|
|
||||||
private MerlinTheWizard merlinTheWizard;
|
|
||||||
private List<String> messagesQueue = new ArrayList<>();
|
private List<String> messagesQueue = new ArrayList<>();
|
||||||
|
|
||||||
MagicWebSocketInstance(UserEntity conversationUser, String connectionUrl, String webSocketTicket) {
|
MagicWebSocketInstance(UserEntity conversationUser, String connectionUrl, String webSocketTicket) {
|
||||||
@ -93,11 +89,9 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
this.conversationUser = conversationUser;
|
this.conversationUser = conversationUser;
|
||||||
this.webSocketTicket = webSocketTicket;
|
this.webSocketTicket = webSocketTicket;
|
||||||
this.webSocketConnectionHelper = new WebSocketConnectionHelper();
|
this.webSocketConnectionHelper = new WebSocketConnectionHelper();
|
||||||
this.displayNameHashMap = new HashMap<>();
|
this.usersHashMap = new HashMap<>();
|
||||||
this.userIdSesssionHashMap = new HashMap<>();
|
|
||||||
magicMap = new MagicMap();
|
magicMap = new MagicMap();
|
||||||
|
|
||||||
merlinTheWizard = new MerlinTheWizard();
|
|
||||||
connected = false;
|
connected = false;
|
||||||
eventBus.register(this);
|
eventBus.register(this);
|
||||||
|
|
||||||
@ -133,7 +127,7 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
private void restartWebSocket() {
|
private void restartWebSocket() {
|
||||||
reconnecting = true;
|
reconnecting = true;
|
||||||
|
|
||||||
if (merlinTheWizard.getMerlinsBeard().hasInternetAccess()) {
|
if (MerlinTheWizard.isConnectedToInternet()) {
|
||||||
Request request = new Request.Builder().url(connectionUrl).build();
|
Request request = new Request.Builder().url(connectionUrl).build();
|
||||||
okHttpClient.newWebSocket(request, this);
|
okHttpClient.newWebSocket(request, this);
|
||||||
restartCount++;
|
restartCount++;
|
||||||
@ -155,6 +149,7 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
connected = true;
|
connected = true;
|
||||||
reconnecting = false;
|
reconnecting = false;
|
||||||
restartCount = 0;
|
restartCount = 0;
|
||||||
|
String oldResumeId = resumeId;
|
||||||
HelloResponseOverallWebSocketMessage helloResponseWebSocketMessage = LoganSquare.parse(text, HelloResponseOverallWebSocketMessage.class);
|
HelloResponseOverallWebSocketMessage helloResponseWebSocketMessage = LoganSquare.parse(text, HelloResponseOverallWebSocketMessage.class);
|
||||||
resumeId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getResumeId();
|
resumeId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getResumeId();
|
||||||
sessionId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getSessionId();
|
sessionId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getSessionId();
|
||||||
@ -165,7 +160,11 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
messagesQueue = new ArrayList<>();
|
messagesQueue = new ArrayList<>();
|
||||||
eventBus.post(new WebSocketCommunicationEvent("hello", null));
|
HashMap<String, String> helloHasHap = new HashMap<>();
|
||||||
|
if (!TextUtils.isEmpty(oldResumeId)) {
|
||||||
|
helloHasHap.put("oldResumeId", oldResumeId);
|
||||||
|
}
|
||||||
|
eventBus.post(new WebSocketCommunicationEvent("hello", helloHasHap));
|
||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
ErrorOverallWebSocketMessage errorOverallWebSocketMessage = LoganSquare.parse(text, ErrorOverallWebSocketMessage.class);
|
ErrorOverallWebSocketMessage errorOverallWebSocketMessage = LoganSquare.parse(text, ErrorOverallWebSocketMessage.class);
|
||||||
@ -187,8 +186,7 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
joinRoomHashMap.put("roomToken", currentRoomToken);
|
joinRoomHashMap.put("roomToken", currentRoomToken);
|
||||||
eventBus.post(new WebSocketCommunicationEvent("roomJoined", joinRoomHashMap));
|
eventBus.post(new WebSocketCommunicationEvent("roomJoined", joinRoomHashMap));
|
||||||
} else {
|
} else {
|
||||||
userIdSesssionHashMap = new HashMap<>();
|
usersHashMap = new HashMap<>();
|
||||||
displayNameHashMap = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "event":
|
case "event":
|
||||||
@ -216,11 +214,14 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
} else if (eventOverallWebSocketMessage.getEventMap().get("type").equals("join")) {
|
} else if (eventOverallWebSocketMessage.getEventMap().get("type").equals("join")) {
|
||||||
List<HashMap<String, Object>> joinEventMap = (List<HashMap<String, Object>>) eventOverallWebSocketMessage.getEventMap().get("join");
|
List<HashMap<String, Object>> joinEventMap = (List<HashMap<String, Object>>) eventOverallWebSocketMessage.getEventMap().get("join");
|
||||||
HashMap<String, Object> internalHashMap;
|
HashMap<String, Object> internalHashMap;
|
||||||
|
Participant participant;
|
||||||
for (int i = 0; i < joinEventMap.size(); i++) {
|
for (int i = 0; i < joinEventMap.size(); i++) {
|
||||||
internalHashMap = joinEventMap.get(i);
|
internalHashMap = joinEventMap.get(i);
|
||||||
HashMap<String, Object> userMap = (HashMap<String, Object>) internalHashMap.get("user");
|
HashMap<String, Object> userMap = (HashMap<String, Object>) internalHashMap.get("user");
|
||||||
displayNameHashMap.put((String) internalHashMap.get("sessionid"), (String) userMap.get("displayname"));
|
participant = new Participant();
|
||||||
userIdSesssionHashMap.put((String) internalHashMap.get("userid"), (String) internalHashMap.get("sessionid"));
|
participant.setUserId((String) internalHashMap.get("userid"));
|
||||||
|
participant.setDisplayName((String) userMap.get("displayname"));
|
||||||
|
usersHashMap.put((String) internalHashMap.get("sessionid"), participant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -359,15 +360,29 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplayNameForSession(String session) {
|
public String getDisplayNameForSession(String session) {
|
||||||
if (displayNameHashMap.containsKey(session)) {
|
if (usersHashMap.containsKey(session)) {
|
||||||
return displayNameHashMap.get(session);
|
return usersHashMap.get(session).getDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextcloudTalkApplication.getSharedApplication().getString(R.string.nc_nick_guest);
|
return NextcloudTalkApplication.getSharedApplication().getString(R.string.nc_nick_guest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSessionForUserId(String userId) {
|
public String getSessionForUserId(String userId) {
|
||||||
return userIdSesssionHashMap.get(userId);
|
for (String session : usersHashMap.keySet()) {
|
||||||
|
if (userId.equals(usersHashMap.get(session).getUserId())) {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserIdForSession(String session) {
|
||||||
|
if (usersHashMap.containsKey(session)) {
|
||||||
|
return usersHashMap.get(session).getUserId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
@ -376,5 +391,4 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
restartWebSocket();
|
restartWebSocket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<!-- Set before a release -->
|
<!-- Set before a release -->
|
||||||
<string name="nc_talk_database_encryption_key" translatable="false">HvAfHtAy/QdFYqAWFFXa1VV_Iv6ZQ1.tf5swMc^45wS_vz=Wm[oyRP5D-</string>
|
<string name="nc_talk_database_encryption_key" translatable="false">HvAfHtAy/QdFYqAWFFXa1VV_Iv6ZQ1.tf5swMc^45wS_vz=Wm[oyRP5D-</string>
|
||||||
<string name="nc_talk_login_scheme" translatable="false">nc</string>
|
<string name="nc_talk_login_scheme" translatable="false">nc</string>
|
||||||
<bool name="nc_is_debug">true</bool>
|
<bool name="nc_is_debug">false</bool>
|
||||||
|
|
||||||
<string name="nc_app_name">Nextcloud Talk</string>
|
<string name="nc_app_name">Nextcloud Talk</string>
|
||||||
<string name="nc_server_product_name">Nextcloud</string>
|
<string name="nc_server_product_name">Nextcloud</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user