mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-22 21:19:31 +01:00
Merge pull request #2543 from nextcloud/add-interface-for-sending-signaling-messages
Add interface for sending signaling messages
This commit is contained in:
commit
e4e9a51889
@ -66,7 +66,6 @@ import com.nextcloud.talk.events.ConfigurationChangeEvent;
|
|||||||
import com.nextcloud.talk.events.MediaStreamEvent;
|
import com.nextcloud.talk.events.MediaStreamEvent;
|
||||||
import com.nextcloud.talk.events.NetworkEvent;
|
import com.nextcloud.talk.events.NetworkEvent;
|
||||||
import com.nextcloud.talk.events.PeerConnectionEvent;
|
import com.nextcloud.talk.events.PeerConnectionEvent;
|
||||||
import com.nextcloud.talk.events.SessionDescriptionSendEvent;
|
|
||||||
import com.nextcloud.talk.events.WebSocketCommunicationEvent;
|
import com.nextcloud.talk.events.WebSocketCommunicationEvent;
|
||||||
import com.nextcloud.talk.models.ExternalSignalingServer;
|
import com.nextcloud.talk.models.ExternalSignalingServer;
|
||||||
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall;
|
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall;
|
||||||
@ -79,13 +78,13 @@ import com.nextcloud.talk.models.json.participants.ParticipantsOverall;
|
|||||||
import com.nextcloud.talk.models.json.signaling.DataChannelMessage;
|
import com.nextcloud.talk.models.json.signaling.DataChannelMessage;
|
||||||
import com.nextcloud.talk.models.json.signaling.DataChannelMessageNick;
|
import com.nextcloud.talk.models.json.signaling.DataChannelMessageNick;
|
||||||
import com.nextcloud.talk.models.json.signaling.NCMessagePayload;
|
import com.nextcloud.talk.models.json.signaling.NCMessagePayload;
|
||||||
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.signaling.Signaling;
|
import com.nextcloud.talk.models.json.signaling.Signaling;
|
||||||
import com.nextcloud.talk.models.json.signaling.SignalingOverall;
|
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.IceServer;
|
||||||
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
|
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
|
||||||
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
|
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
|
||||||
|
import com.nextcloud.talk.signaling.SignalingMessageSender;
|
||||||
import com.nextcloud.talk.ui.dialog.AudioOutputDialog;
|
import com.nextcloud.talk.ui.dialog.AudioOutputDialog;
|
||||||
import com.nextcloud.talk.users.UserManager;
|
import com.nextcloud.talk.users.UserManager;
|
||||||
import com.nextcloud.talk.utils.ApiUtils;
|
import com.nextcloud.talk.utils.ApiUtils;
|
||||||
@ -262,6 +261,9 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
private InternalSignalingMessageReceiver internalSignalingMessageReceiver = new InternalSignalingMessageReceiver();
|
private InternalSignalingMessageReceiver internalSignalingMessageReceiver = new InternalSignalingMessageReceiver();
|
||||||
private SignalingMessageReceiver signalingMessageReceiver;
|
private SignalingMessageReceiver signalingMessageReceiver;
|
||||||
|
|
||||||
|
private InternalSignalingMessageSender internalSignalingMessageSender = new InternalSignalingMessageSender();
|
||||||
|
private SignalingMessageSender signalingMessageSender;
|
||||||
|
|
||||||
private Map<String, SignalingMessageReceiver.CallParticipantMessageListener> callParticipantMessageListeners =
|
private Map<String, SignalingMessageReceiver.CallParticipantMessageListener> callParticipantMessageListeners =
|
||||||
new HashMap<>();
|
new HashMap<>();
|
||||||
|
|
||||||
@ -1369,6 +1371,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
signalingMessageReceiver = internalSignalingMessageReceiver;
|
signalingMessageReceiver = internalSignalingMessageReceiver;
|
||||||
signalingMessageReceiver.addListener(participantListMessageListener);
|
signalingMessageReceiver.addListener(participantListMessageListener);
|
||||||
signalingMessageReceiver.addListener(offerMessageListener);
|
signalingMessageReceiver.addListener(offerMessageListener);
|
||||||
|
signalingMessageSender = internalSignalingMessageSender;
|
||||||
joinRoomAndCall();
|
joinRoomAndCall();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1572,6 +1575,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
signalingMessageReceiver = webSocketClient.getSignalingMessageReceiver();
|
signalingMessageReceiver = webSocketClient.getSignalingMessageReceiver();
|
||||||
signalingMessageReceiver.addListener(participantListMessageListener);
|
signalingMessageReceiver.addListener(participantListMessageListener);
|
||||||
signalingMessageReceiver.addListener(offerMessageListener);
|
signalingMessageReceiver.addListener(offerMessageListener);
|
||||||
|
signalingMessageSender = webSocketClient.getSignalingMessageSender();
|
||||||
} else {
|
} else {
|
||||||
if (webSocketClient.isConnected() && currentCallStatus == CallStatus.PUBLISHER_FAILED) {
|
if (webSocketClient.isConnected() && currentCallStatus == CallStatus.PUBLISHER_FAILED) {
|
||||||
webSocketClient.restartWebSocket();
|
webSocketClient.restartWebSocket();
|
||||||
@ -1615,11 +1619,6 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
performCall();
|
performCall();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "peerReadyForRequestingOffer":
|
|
||||||
Log.d(TAG, "onMessageEvent 'peerReadyForRequestingOffer'");
|
|
||||||
webSocketClient.requestOfferForSessionIdWithType(
|
|
||||||
webSocketCommunicationEvent.getHashMap().get("sessionId"), "video");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1955,7 +1954,8 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
type,
|
type,
|
||||||
signalingMessageReceiver);
|
signalingMessageReceiver,
|
||||||
|
signalingMessageSender);
|
||||||
|
|
||||||
} else if (hasMCU) {
|
} else if (hasMCU) {
|
||||||
peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory,
|
peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory,
|
||||||
@ -1967,7 +1967,8 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
type,
|
type,
|
||||||
signalingMessageReceiver);
|
signalingMessageReceiver,
|
||||||
|
signalingMessageSender);
|
||||||
} else {
|
} else {
|
||||||
if (!"screen".equals(type)) {
|
if (!"screen".equals(type)) {
|
||||||
peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory,
|
peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory,
|
||||||
@ -1979,7 +1980,8 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
type,
|
type,
|
||||||
signalingMessageReceiver);
|
signalingMessageReceiver,
|
||||||
|
signalingMessageSender);
|
||||||
} else {
|
} else {
|
||||||
peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory,
|
peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory,
|
||||||
iceServers,
|
iceServers,
|
||||||
@ -1990,7 +1992,8 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
type,
|
type,
|
||||||
signalingMessageReceiver);
|
signalingMessageReceiver,
|
||||||
|
signalingMessageSender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2234,80 +2237,6 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
|
||||||
public void onMessageEvent(SessionDescriptionSendEvent sessionDescriptionSend) throws IOException {
|
|
||||||
NCMessageWrapper ncMessageWrapper = new NCMessageWrapper();
|
|
||||||
ncMessageWrapper.setEv("message");
|
|
||||||
ncMessageWrapper.setSessionId(callSession);
|
|
||||||
NCSignalingMessage ncSignalingMessage = new NCSignalingMessage();
|
|
||||||
ncSignalingMessage.setTo(sessionDescriptionSend.getPeerId());
|
|
||||||
ncSignalingMessage.setRoomType(sessionDescriptionSend.getVideoStreamType());
|
|
||||||
ncSignalingMessage.setType(sessionDescriptionSend.getType());
|
|
||||||
NCMessagePayload ncMessagePayload = new NCMessagePayload();
|
|
||||||
ncMessagePayload.setType(sessionDescriptionSend.getType());
|
|
||||||
|
|
||||||
if (!"candidate".equals(sessionDescriptionSend.getType())) {
|
|
||||||
ncMessagePayload.setSdp(sessionDescriptionSend.getSessionDescription().description);
|
|
||||||
ncMessagePayload.setNick(conversationUser.getDisplayName());
|
|
||||||
} else {
|
|
||||||
ncMessagePayload.setIceCandidate(sessionDescriptionSend.getNcIceCandidate());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set all we need
|
|
||||||
ncSignalingMessage.setPayload(ncMessagePayload);
|
|
||||||
ncMessageWrapper.setSignalingMessage(ncSignalingMessage);
|
|
||||||
|
|
||||||
|
|
||||||
if (!hasExternalSignalingServer) {
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
stringBuilder.append("{")
|
|
||||||
.append("\"fn\":\"")
|
|
||||||
.append(StringEscapeUtils.escapeJson(LoganSquare.serialize(ncMessageWrapper.getSignalingMessage())))
|
|
||||||
.append("\"")
|
|
||||||
.append(",")
|
|
||||||
.append("\"sessionId\":")
|
|
||||||
.append("\"").append(StringEscapeUtils.escapeJson(callSession)).append("\"")
|
|
||||||
.append(",")
|
|
||||||
.append("\"ev\":\"message\"")
|
|
||||||
.append("}");
|
|
||||||
|
|
||||||
List<String> strings = new ArrayList<>();
|
|
||||||
String stringToSend = stringBuilder.toString();
|
|
||||||
strings.add(stringToSend);
|
|
||||||
|
|
||||||
int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[]{ApiUtils.APIv3, 2, 1});
|
|
||||||
|
|
||||||
ncApi.sendSignalingMessages(credentials, ApiUtils.getUrlForSignaling(apiVersion, baseUrl, roomToken),
|
|
||||||
strings.toString())
|
|
||||||
.retry(3)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.subscribe(new Observer<SignalingOverall>() {
|
|
||||||
@Override
|
|
||||||
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(@io.reactivex.annotations.NonNull SignalingOverall signalingOverall) {
|
|
||||||
receivedSignalingMessages(signalingOverall.getOcs().getSignalings());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
webSocketClient.sendCallMessage(ncMessageWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||||
@NonNull int[] grantResults) {
|
@NonNull int[] grantResults) {
|
||||||
@ -2644,6 +2573,93 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class InternalSignalingMessageSender implements SignalingMessageSender {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(NCSignalingMessage ncSignalingMessage) {
|
||||||
|
addLocalParticipantNickIfNeeded(ncSignalingMessage);
|
||||||
|
|
||||||
|
String serializedNcSignalingMessage;
|
||||||
|
try {
|
||||||
|
serializedNcSignalingMessage = LoganSquare.serialize(ncSignalingMessage);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Failed to serialize signaling message", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The message wrapper can not be defined in a JSON model to be directly serialized, as sent messages
|
||||||
|
// need to be serialized twice; first the signaling message, and then the wrapper as a whole. Received
|
||||||
|
// messages, on the other hand, just need to be deserialized once.
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.append('{')
|
||||||
|
.append("\"fn\":\"")
|
||||||
|
.append(StringEscapeUtils.escapeJson(serializedNcSignalingMessage))
|
||||||
|
.append('\"')
|
||||||
|
.append(',')
|
||||||
|
.append("\"sessionId\":")
|
||||||
|
.append('\"').append(StringEscapeUtils.escapeJson(callSession)).append('\"')
|
||||||
|
.append(',')
|
||||||
|
.append("\"ev\":\"message\"")
|
||||||
|
.append('}');
|
||||||
|
|
||||||
|
List<String> strings = new ArrayList<>();
|
||||||
|
String stringToSend = stringBuilder.toString();
|
||||||
|
strings.add(stringToSend);
|
||||||
|
|
||||||
|
int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[]{ApiUtils.APIv3, 2, 1});
|
||||||
|
|
||||||
|
ncApi.sendSignalingMessages(credentials, ApiUtils.getUrlForSignaling(apiVersion, baseUrl, roomToken),
|
||||||
|
strings.toString())
|
||||||
|
.retry(3)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.subscribe(new Observer<SignalingOverall>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(@io.reactivex.annotations.NonNull SignalingOverall signalingOverall) {
|
||||||
|
// When sending messages to the internal signaling server the response has been empty since
|
||||||
|
// Talk v2.9.0, so it is not really needed to process it, but there is no harm either in
|
||||||
|
// doing that, as technically messages could be returned.
|
||||||
|
receivedSignalingMessages(signalingOverall.getOcs().getSignalings());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
|
||||||
|
Log.e(TAG, "", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the local participant nick to offers and answers.
|
||||||
|
*
|
||||||
|
* For legacy reasons the offers and answers sent when the internal signaling server is used are expected to
|
||||||
|
* provide the nick of the local participant.
|
||||||
|
*
|
||||||
|
* @param ncSignalingMessage the message to add the nick to
|
||||||
|
*/
|
||||||
|
private void addLocalParticipantNickIfNeeded(NCSignalingMessage ncSignalingMessage) {
|
||||||
|
String type = ncSignalingMessage.getType();
|
||||||
|
if (!"offer".equals(type) && !"answer".equals(type)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NCMessagePayload payload = ncSignalingMessage.getPayload();
|
||||||
|
if (payload == null) {
|
||||||
|
// Broken message, this should not happen
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.setNick(conversationUser.getDisplayName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class MicrophoneButtonTouchListener implements View.OnTouchListener {
|
private class MicrophoneButtonTouchListener implements View.OnTouchListener {
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk application
|
|
||||||
*
|
|
||||||
* @author Mario Danic
|
|
||||||
* Copyright (C) 2017 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.events;
|
|
||||||
|
|
||||||
import com.nextcloud.talk.models.json.signaling.NCIceCandidate;
|
|
||||||
|
|
||||||
import org.webrtc.SessionDescription;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
public class SessionDescriptionSendEvent {
|
|
||||||
@Nullable
|
|
||||||
private final SessionDescription sessionDescription;
|
|
||||||
private final String peerId;
|
|
||||||
private final String type;
|
|
||||||
@Nullable
|
|
||||||
private final NCIceCandidate ncIceCandidate;
|
|
||||||
private final String videoStreamType;
|
|
||||||
|
|
||||||
public SessionDescriptionSendEvent(@Nullable SessionDescription sessionDescription, String peerId, String type,
|
|
||||||
@Nullable NCIceCandidate ncIceCandidate, @Nullable String videoStreamType) {
|
|
||||||
this.sessionDescription = sessionDescription;
|
|
||||||
this.peerId = peerId;
|
|
||||||
this.type = type;
|
|
||||||
this.ncIceCandidate = ncIceCandidate;
|
|
||||||
this.videoStreamType = videoStreamType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public SessionDescription getSessionDescription() {
|
|
||||||
return this.sessionDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPeerId() {
|
|
||||||
return this.peerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public NCIceCandidate getNcIceCandidate() {
|
|
||||||
return this.ncIceCandidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVideoStreamType() {
|
|
||||||
return this.videoStreamType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (o == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(o instanceof SessionDescriptionSendEvent)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final SessionDescriptionSendEvent other = (SessionDescriptionSendEvent) o;
|
|
||||||
if (!other.canEqual((Object) this)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Object this$sessionDescription = this.getSessionDescription();
|
|
||||||
final Object other$sessionDescription = other.getSessionDescription();
|
|
||||||
if (this$sessionDescription == null ? other$sessionDescription != null : !this$sessionDescription.equals(other$sessionDescription)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Object this$peerId = this.getPeerId();
|
|
||||||
final Object other$peerId = other.getPeerId();
|
|
||||||
if (this$peerId == null ? other$peerId != null : !this$peerId.equals(other$peerId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Object this$type = this.getType();
|
|
||||||
final Object other$type = other.getType();
|
|
||||||
if (this$type == null ? other$type != null : !this$type.equals(other$type)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Object this$ncIceCandidate = this.getNcIceCandidate();
|
|
||||||
final Object other$ncIceCandidate = other.getNcIceCandidate();
|
|
||||||
if (this$ncIceCandidate == null ? other$ncIceCandidate != null : !this$ncIceCandidate.equals(other$ncIceCandidate)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Object this$videoStreamType = this.getVideoStreamType();
|
|
||||||
final Object other$videoStreamType = other.getVideoStreamType();
|
|
||||||
|
|
||||||
return this$videoStreamType == null ? other$videoStreamType == null : this$videoStreamType.equals(other$videoStreamType);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean canEqual(final Object other) {
|
|
||||||
return other instanceof SessionDescriptionSendEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
final int PRIME = 59;
|
|
||||||
int result = 1;
|
|
||||||
final Object $sessionDescription = this.getSessionDescription();
|
|
||||||
result = result * PRIME + ($sessionDescription == null ? 43 : $sessionDescription.hashCode());
|
|
||||||
final Object $peerId = this.getPeerId();
|
|
||||||
result = result * PRIME + ($peerId == null ? 43 : $peerId.hashCode());
|
|
||||||
final Object $type = this.getType();
|
|
||||||
result = result * PRIME + ($type == null ? 43 : $type.hashCode());
|
|
||||||
final Object $ncIceCandidate = this.getNcIceCandidate();
|
|
||||||
result = result * PRIME + ($ncIceCandidate == null ? 43 : $ncIceCandidate.hashCode());
|
|
||||||
final Object $videoStreamType = this.getVideoStreamType();
|
|
||||||
result = result * PRIME + ($videoStreamType == null ? 43 : $videoStreamType.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "SessionDescriptionSendEvent(sessionDescription=" + this.getSessionDescription() + ", peerId=" + this.getPeerId() + ", type=" + this.getType() + ", ncIceCandidate=" + this.getNcIceCandidate() + ", videoStreamType=" + this.getVideoStreamType() + ")";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk application
|
|
||||||
*
|
|
||||||
* @author Mario Danic
|
|
||||||
* @author Andy Scherzinger
|
|
||||||
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
|
||||||
* Copyright (C) 2017 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.models.json.signaling
|
|
||||||
|
|
||||||
import android.os.Parcelable
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
|
||||||
import kotlinx.android.parcel.Parcelize
|
|
||||||
|
|
||||||
@Parcelize
|
|
||||||
@JsonObject
|
|
||||||
data class NCMessageWrapper(
|
|
||||||
@JsonField(name = ["fn"])
|
|
||||||
var signalingMessage: NCSignalingMessage? = null,
|
|
||||||
/** always a "message" */
|
|
||||||
@JsonField(name = ["ev"])
|
|
||||||
var ev: String? = null,
|
|
||||||
@JsonField(name = ["sessionId"])
|
|
||||||
var sessionId: String? = null
|
|
||||||
) : Parcelable {
|
|
||||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
|
||||||
constructor() : this(null, null, null)
|
|
||||||
}
|
|
@ -34,7 +34,7 @@ import kotlinx.android.parcel.TypeParceler
|
|||||||
data class Signaling(
|
data class Signaling(
|
||||||
@JsonField(name = ["type"])
|
@JsonField(name = ["type"])
|
||||||
var type: String? = null,
|
var type: String? = null,
|
||||||
/** can be NCMessageWrapper or List<HashMap<String,String>> */
|
/** can be NCSignalingMessage (encoded as a String) or List<Map<String, Object>> */
|
||||||
@JsonField(name = ["data"])
|
@JsonField(name = ["data"])
|
||||||
var messageWrapper: Any? = null
|
var messageWrapper: Any? = null
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk application
|
|
||||||
*
|
|
||||||
* @author Mario Danic
|
|
||||||
* @author Andy Scherzinger
|
|
||||||
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
|
||||||
* 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.models.json.websocket
|
|
||||||
|
|
||||||
import android.os.Parcelable
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
|
||||||
import kotlinx.android.parcel.Parcelize
|
|
||||||
|
|
||||||
@Parcelize
|
|
||||||
@JsonObject
|
|
||||||
data class RequestOfferOverallWebSocketMessage(
|
|
||||||
@JsonField(name = ["type"])
|
|
||||||
var type: String? = null,
|
|
||||||
@JsonField(name = ["message"])
|
|
||||||
var requestOfferOverallWebSocketMessage: RequestOfferSignalingMessage? = null
|
|
||||||
) : Parcelable {
|
|
||||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
|
||||||
constructor() : this(null, null)
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk application
|
|
||||||
*
|
|
||||||
* @author Mario Danic
|
|
||||||
* @author Andy Scherzinger
|
|
||||||
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
|
||||||
* 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.models.json.websocket
|
|
||||||
|
|
||||||
import android.os.Parcelable
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
|
||||||
import kotlinx.android.parcel.Parcelize
|
|
||||||
|
|
||||||
@Parcelize
|
|
||||||
@JsonObject
|
|
||||||
class RequestOfferSignalingMessage(
|
|
||||||
@JsonField(name = ["recipient"])
|
|
||||||
var actorWebSocketMessage: ActorWebSocketMessage? = null,
|
|
||||||
@JsonField(name = ["data"])
|
|
||||||
var signalingDataWebSocketMessageForOffer: SignalingDataWebSocketMessageForOffer? = null
|
|
||||||
) : Parcelable {
|
|
||||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
|
||||||
constructor() : this(null, null)
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk application
|
|
||||||
*
|
|
||||||
* @author Mario Danic
|
|
||||||
* @author Andy Scherzinger
|
|
||||||
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
|
|
||||||
* 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.models.json.websocket
|
|
||||||
|
|
||||||
import android.os.Parcelable
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject
|
|
||||||
import kotlinx.android.parcel.Parcelize
|
|
||||||
|
|
||||||
@Parcelize
|
|
||||||
@JsonObject
|
|
||||||
class SignalingDataWebSocketMessageForOffer(
|
|
||||||
@JsonField(name = ["type"])
|
|
||||||
var type: String? = null,
|
|
||||||
@JsonField(name = ["roomType"])
|
|
||||||
var roomType: String? = null
|
|
||||||
) : Parcelable {
|
|
||||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
|
||||||
constructor() : this(null, null)
|
|
||||||
}
|
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Daniel Calviño Sánchez
|
||||||
|
* Copyright (C) 2022 Daniel Calviño Sánchez <danxuliu@gmail.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.signaling;
|
||||||
|
|
||||||
|
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to send signaling messages.
|
||||||
|
*/
|
||||||
|
public interface SignalingMessageSender {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the given signaling message.
|
||||||
|
*
|
||||||
|
* @param ncSignalingMessage the message to send
|
||||||
|
*/
|
||||||
|
void send(NCSignalingMessage ncSignalingMessage);
|
||||||
|
|
||||||
|
}
|
@ -31,7 +31,6 @@ import com.nextcloud.talk.data.user.model.User;
|
|||||||
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.json.participants.Participant;
|
import com.nextcloud.talk.models.json.participants.Participant;
|
||||||
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.BaseWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.BaseWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.ByeWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.ByeWebSocketMessage;
|
||||||
@ -41,6 +40,7 @@ import com.nextcloud.talk.models.json.websocket.EventOverallWebSocketMessage;
|
|||||||
import com.nextcloud.talk.models.json.websocket.HelloResponseOverallWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.HelloResponseOverallWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.JoinedRoomOverallWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.JoinedRoomOverallWebSocketMessage;
|
||||||
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
|
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
|
||||||
|
import com.nextcloud.talk.signaling.SignalingMessageSender;
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
@ -102,6 +102,8 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
|
|
||||||
private final ExternalSignalingMessageReceiver signalingMessageReceiver = new ExternalSignalingMessageReceiver();
|
private final ExternalSignalingMessageReceiver signalingMessageReceiver = new ExternalSignalingMessageReceiver();
|
||||||
|
|
||||||
|
private final ExternalSignalingMessageSender signalingMessageSender = new ExternalSignalingMessageSender();
|
||||||
|
|
||||||
MagicWebSocketInstance(User conversationUser, String connectionUrl, String webSocketTicket) {
|
MagicWebSocketInstance(User conversationUser, String connectionUrl, String webSocketTicket) {
|
||||||
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
|
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
|
||||||
|
|
||||||
@ -344,9 +346,9 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendCallMessage(NCMessageWrapper ncMessageWrapper) {
|
private void sendCallMessage(NCSignalingMessage ncSignalingMessage) {
|
||||||
try {
|
try {
|
||||||
String message = LoganSquare.serialize(webSocketConnectionHelper.getAssembledCallMessageModel(ncMessageWrapper));
|
String message = LoganSquare.serialize(webSocketConnectionHelper.getAssembledCallMessageModel(ncSignalingMessage));
|
||||||
if (!connected || reconnecting) {
|
if (!connected || reconnecting) {
|
||||||
messagesQueue.add(message);
|
messagesQueue.add(message);
|
||||||
} else {
|
} else {
|
||||||
@ -357,19 +359,6 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestOfferForSessionIdWithType(String sessionIdParam, String roomType) {
|
|
||||||
try {
|
|
||||||
String message = LoganSquare.serialize(webSocketConnectionHelper.getAssembledRequestOfferModel(sessionIdParam, roomType));
|
|
||||||
if (!connected || reconnecting) {
|
|
||||||
messagesQueue.add(message);
|
|
||||||
} else {
|
|
||||||
internalWebSocket.send(message);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Failed to offer request. sessionIdParam: " + sessionIdParam + " roomType:" + roomType, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendBye() {
|
void sendBye() {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
try {
|
try {
|
||||||
@ -420,6 +409,10 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
return signalingMessageReceiver;
|
return signalingMessageReceiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SignalingMessageSender getSignalingMessageSender() {
|
||||||
|
return signalingMessageSender;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary implementation of SignalingMessageReceiver until signaling related code is extracted to a Signaling
|
* Temporary implementation of SignalingMessageReceiver until signaling related code is extracted to a Signaling
|
||||||
* class.
|
* class.
|
||||||
@ -436,4 +429,11 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
processSignalingMessage(message);
|
processSignalingMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ExternalSignalingMessageSender implements SignalingMessageSender {
|
||||||
|
@Override
|
||||||
|
public void send(NCSignalingMessage ncSignalingMessage) {
|
||||||
|
sendCallMessage(ncSignalingMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,12 +32,13 @@ import com.nextcloud.talk.R;
|
|||||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||||
import com.nextcloud.talk.events.MediaStreamEvent;
|
import com.nextcloud.talk.events.MediaStreamEvent;
|
||||||
import com.nextcloud.talk.events.PeerConnectionEvent;
|
import com.nextcloud.talk.events.PeerConnectionEvent;
|
||||||
import com.nextcloud.talk.events.SessionDescriptionSendEvent;
|
|
||||||
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.DataChannelMessageNick;
|
import com.nextcloud.talk.models.json.signaling.DataChannelMessageNick;
|
||||||
import com.nextcloud.talk.models.json.signaling.NCIceCandidate;
|
import com.nextcloud.talk.models.json.signaling.NCIceCandidate;
|
||||||
|
import com.nextcloud.talk.models.json.signaling.NCMessagePayload;
|
||||||
|
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
||||||
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
|
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
|
||||||
|
import com.nextcloud.talk.signaling.SignalingMessageSender;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.webrtc.AudioTrack;
|
import org.webrtc.AudioTrack;
|
||||||
@ -78,6 +79,8 @@ public class PeerConnectionWrapper {
|
|||||||
private final SignalingMessageReceiver signalingMessageReceiver;
|
private final SignalingMessageReceiver signalingMessageReceiver;
|
||||||
private final WebRtcMessageListener webRtcMessageListener = new WebRtcMessageListener();
|
private final WebRtcMessageListener webRtcMessageListener = new WebRtcMessageListener();
|
||||||
|
|
||||||
|
private final SignalingMessageSender signalingMessageSender;
|
||||||
|
|
||||||
private List<IceCandidate> iceCandidates = new ArrayList<>();
|
private List<IceCandidate> iceCandidates = new ArrayList<>();
|
||||||
private PeerConnection peerConnection;
|
private PeerConnection peerConnection;
|
||||||
private String sessionId;
|
private String sessionId;
|
||||||
@ -101,7 +104,8 @@ public class PeerConnectionWrapper {
|
|||||||
MediaConstraints mediaConstraints,
|
MediaConstraints mediaConstraints,
|
||||||
String sessionId, String localSession, @Nullable MediaStream localStream,
|
String sessionId, String localSession, @Nullable MediaStream localStream,
|
||||||
boolean isMCUPublisher, boolean hasMCU, String videoStreamType,
|
boolean isMCUPublisher, boolean hasMCU, String videoStreamType,
|
||||||
SignalingMessageReceiver signalingMessageReceiver) {
|
SignalingMessageReceiver signalingMessageReceiver,
|
||||||
|
SignalingMessageSender signalingMessageSender) {
|
||||||
|
|
||||||
Objects.requireNonNull(NextcloudTalkApplication.Companion.getSharedApplication()).getComponentApplication().inject(this);
|
Objects.requireNonNull(NextcloudTalkApplication.Companion.getSharedApplication()).getComponentApplication().inject(this);
|
||||||
|
|
||||||
@ -122,6 +126,8 @@ public class PeerConnectionWrapper {
|
|||||||
this.signalingMessageReceiver = signalingMessageReceiver;
|
this.signalingMessageReceiver = signalingMessageReceiver;
|
||||||
this.signalingMessageReceiver.addListener(webRtcMessageListener, sessionId, videoStreamType);
|
this.signalingMessageReceiver.addListener(webRtcMessageListener, sessionId, videoStreamType);
|
||||||
|
|
||||||
|
this.signalingMessageSender = signalingMessageSender;
|
||||||
|
|
||||||
if (peerConnection != null) {
|
if (peerConnection != null) {
|
||||||
if (this.localStream != null) {
|
if (this.localStream != null) {
|
||||||
List<String> localStreamIds = Collections.singletonList(this.localStream.getId());
|
List<String> localStreamIds = Collections.singletonList(this.localStream.getId());
|
||||||
@ -143,9 +149,10 @@ public class PeerConnectionWrapper {
|
|||||||
} else if (hasMCU && this.videoStreamType.equals("video")) {
|
} else if (hasMCU && this.videoStreamType.equals("video")) {
|
||||||
// If the connection type is "screen" the client sharing the screen will send an
|
// If the connection type is "screen" the client sharing the screen will send an
|
||||||
// offer; offers should be requested only for videos.
|
// offer; offers should be requested only for videos.
|
||||||
HashMap<String, String> hashMap = new HashMap<>();
|
// "to" property is not actually needed in the "requestoffer" signaling message, but it is used to
|
||||||
hashMap.put("sessionId", sessionId);
|
// set the recipient session ID in the assembled call message.
|
||||||
EventBus.getDefault().post(new WebSocketCommunicationEvent("peerReadyForRequestingOffer", hashMap));
|
NCSignalingMessage ncSignalingMessage = createBaseSignalingMessage("requestoffer");
|
||||||
|
signalingMessageSender.send(ncSignalingMessage);
|
||||||
} else if (!hasMCU && hasInitiated) {
|
} else if (!hasMCU && hasInitiated) {
|
||||||
peerConnection.createOffer(magicSdpObserver, mediaConstraints);
|
peerConnection.createOffer(magicSdpObserver, mediaConstraints);
|
||||||
}
|
}
|
||||||
@ -269,6 +276,15 @@ public class PeerConnectionWrapper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NCSignalingMessage createBaseSignalingMessage(String type) {
|
||||||
|
NCSignalingMessage ncSignalingMessage = new NCSignalingMessage();
|
||||||
|
ncSignalingMessage.setTo(sessionId);
|
||||||
|
ncSignalingMessage.setRoomType(videoStreamType);
|
||||||
|
ncSignalingMessage.setType(type);
|
||||||
|
|
||||||
|
return ncSignalingMessage;
|
||||||
|
}
|
||||||
|
|
||||||
private class WebRtcMessageListener implements SignalingMessageReceiver.WebRtcMessageListener {
|
private class WebRtcMessageListener implements SignalingMessageReceiver.WebRtcMessageListener {
|
||||||
|
|
||||||
public void onOffer(String sdp, String nick) {
|
public void onOffer(String sdp, String nick) {
|
||||||
@ -425,12 +441,19 @@ public class PeerConnectionWrapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIceCandidate(IceCandidate iceCandidate) {
|
public void onIceCandidate(IceCandidate iceCandidate) {
|
||||||
|
NCSignalingMessage ncSignalingMessage = createBaseSignalingMessage("candidate");
|
||||||
|
NCMessagePayload ncMessagePayload = new NCMessagePayload();
|
||||||
|
ncMessagePayload.setType("candidate");
|
||||||
|
|
||||||
NCIceCandidate ncIceCandidate = new NCIceCandidate();
|
NCIceCandidate ncIceCandidate = new NCIceCandidate();
|
||||||
ncIceCandidate.setSdpMid(iceCandidate.sdpMid);
|
ncIceCandidate.setSdpMid(iceCandidate.sdpMid);
|
||||||
ncIceCandidate.setSdpMLineIndex(iceCandidate.sdpMLineIndex);
|
ncIceCandidate.setSdpMLineIndex(iceCandidate.sdpMLineIndex);
|
||||||
ncIceCandidate.setCandidate(iceCandidate.sdp);
|
ncIceCandidate.setCandidate(iceCandidate.sdp);
|
||||||
EventBus.getDefault().post(new SessionDescriptionSendEvent(null, sessionId,
|
ncMessagePayload.setIceCandidate(ncIceCandidate);
|
||||||
"candidate", ncIceCandidate, videoStreamType));
|
|
||||||
|
ncSignalingMessage.setPayload(ncMessagePayload);
|
||||||
|
|
||||||
|
signalingMessageSender.send(ncSignalingMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -484,6 +507,12 @@ public class PeerConnectionWrapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateSuccess(SessionDescription sessionDescription) {
|
public void onCreateSuccess(SessionDescription sessionDescription) {
|
||||||
|
String type = sessionDescription.type.canonicalForm();
|
||||||
|
|
||||||
|
NCSignalingMessage ncSignalingMessage = createBaseSignalingMessage(type);
|
||||||
|
NCMessagePayload ncMessagePayload = new NCMessagePayload();
|
||||||
|
ncMessagePayload.setType(type);
|
||||||
|
|
||||||
SessionDescription sessionDescriptionWithPreferredCodec;
|
SessionDescription sessionDescriptionWithPreferredCodec;
|
||||||
String sessionDescriptionStringWithPreferredCodec = MagicWebRTCUtils.preferCodec
|
String sessionDescriptionStringWithPreferredCodec = MagicWebRTCUtils.preferCodec
|
||||||
(sessionDescription.description,
|
(sessionDescription.description,
|
||||||
@ -492,9 +521,11 @@ public class PeerConnectionWrapper {
|
|||||||
sessionDescription.type,
|
sessionDescription.type,
|
||||||
sessionDescriptionStringWithPreferredCodec);
|
sessionDescriptionStringWithPreferredCodec);
|
||||||
|
|
||||||
|
ncMessagePayload.setSdp(sessionDescriptionWithPreferredCodec.description);
|
||||||
|
|
||||||
EventBus.getDefault().post(new SessionDescriptionSendEvent(sessionDescriptionWithPreferredCodec, sessionId,
|
ncSignalingMessage.setPayload(ncMessagePayload);
|
||||||
sessionDescription.type.canonicalForm().toLowerCase(), null, videoStreamType));
|
|
||||||
|
signalingMessageSender.send(ncSignalingMessage);
|
||||||
|
|
||||||
if (peerConnection != null) {
|
if (peerConnection != null) {
|
||||||
peerConnection.setLocalDescription(magicSdpObserver, sessionDescriptionWithPreferredCodec);
|
peerConnection.setLocalDescription(magicSdpObserver, sessionDescriptionWithPreferredCodec);
|
||||||
|
@ -25,7 +25,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||||
import com.nextcloud.talk.data.user.model.User;
|
import com.nextcloud.talk.data.user.model.User;
|
||||||
import com.nextcloud.talk.models.json.signaling.NCMessageWrapper;
|
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.ActorWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.ActorWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.AuthParametersWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.AuthParametersWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.AuthWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.AuthWebSocketMessage;
|
||||||
@ -33,11 +33,8 @@ import com.nextcloud.talk.models.json.websocket.CallOverallWebSocketMessage;
|
|||||||
import com.nextcloud.talk.models.json.websocket.CallWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.CallWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.HelloOverallWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.HelloOverallWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.HelloWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.HelloWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.RequestOfferOverallWebSocketMessage;
|
|
||||||
import com.nextcloud.talk.models.json.websocket.RequestOfferSignalingMessage;
|
|
||||||
import com.nextcloud.talk.models.json.websocket.RoomOverallWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.RoomOverallWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.RoomWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.RoomWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.SignalingDataWebSocketMessageForOffer;
|
|
||||||
import com.nextcloud.talk.utils.ApiUtils;
|
import com.nextcloud.talk.utils.ApiUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -146,27 +143,7 @@ public class WebSocketConnectionHelper {
|
|||||||
return roomOverallWebSocketMessage;
|
return roomOverallWebSocketMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestOfferOverallWebSocketMessage getAssembledRequestOfferModel(String sessionId, String roomType) {
|
CallOverallWebSocketMessage getAssembledCallMessageModel(NCSignalingMessage ncSignalingMessage) {
|
||||||
RequestOfferOverallWebSocketMessage requestOfferOverallWebSocketMessage = new RequestOfferOverallWebSocketMessage();
|
|
||||||
requestOfferOverallWebSocketMessage.setType("message");
|
|
||||||
|
|
||||||
RequestOfferSignalingMessage requestOfferSignalingMessage = new RequestOfferSignalingMessage();
|
|
||||||
|
|
||||||
ActorWebSocketMessage actorWebSocketMessage = new ActorWebSocketMessage();
|
|
||||||
actorWebSocketMessage.setType("session");
|
|
||||||
actorWebSocketMessage.setSessionId(sessionId);
|
|
||||||
requestOfferSignalingMessage.setActorWebSocketMessage(actorWebSocketMessage);
|
|
||||||
|
|
||||||
SignalingDataWebSocketMessageForOffer signalingDataWebSocketMessageForOffer = new SignalingDataWebSocketMessageForOffer();
|
|
||||||
signalingDataWebSocketMessageForOffer.setRoomType(roomType);
|
|
||||||
signalingDataWebSocketMessageForOffer.setType("requestoffer");
|
|
||||||
requestOfferSignalingMessage.setSignalingDataWebSocketMessageForOffer(signalingDataWebSocketMessageForOffer);
|
|
||||||
|
|
||||||
requestOfferOverallWebSocketMessage.setRequestOfferOverallWebSocketMessage(requestOfferSignalingMessage);
|
|
||||||
return requestOfferOverallWebSocketMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
CallOverallWebSocketMessage getAssembledCallMessageModel(NCMessageWrapper ncMessageWrapper) {
|
|
||||||
CallOverallWebSocketMessage callOverallWebSocketMessage = new CallOverallWebSocketMessage();
|
CallOverallWebSocketMessage callOverallWebSocketMessage = new CallOverallWebSocketMessage();
|
||||||
callOverallWebSocketMessage.setType("message");
|
callOverallWebSocketMessage.setType("message");
|
||||||
|
|
||||||
@ -174,9 +151,9 @@ public class WebSocketConnectionHelper {
|
|||||||
|
|
||||||
ActorWebSocketMessage actorWebSocketMessage = new ActorWebSocketMessage();
|
ActorWebSocketMessage actorWebSocketMessage = new ActorWebSocketMessage();
|
||||||
actorWebSocketMessage.setType("session");
|
actorWebSocketMessage.setType("session");
|
||||||
actorWebSocketMessage.setSessionId(ncMessageWrapper.getSignalingMessage().getTo());
|
actorWebSocketMessage.setSessionId(ncSignalingMessage.getTo());
|
||||||
callWebSocketMessage.setRecipientWebSocketMessage(actorWebSocketMessage);
|
callWebSocketMessage.setRecipientWebSocketMessage(actorWebSocketMessage);
|
||||||
callWebSocketMessage.setNcSignalingMessage(ncMessageWrapper.getSignalingMessage());
|
callWebSocketMessage.setNcSignalingMessage(ncSignalingMessage);
|
||||||
|
|
||||||
callOverallWebSocketMessage.setCallWebSocketMessage(callWebSocketMessage);
|
callOverallWebSocketMessage.setCallWebSocketMessage(callWebSocketMessage);
|
||||||
return callOverallWebSocketMessage;
|
return callOverallWebSocketMessage;
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
DO NOT TOUCH; GENERATED BY DRONE
|
DO NOT TOUCH; GENERATED BY DRONE
|
||||||
<span class="mdl-layout-title">Lint Report: 112 warnings</span>
|
<span class="mdl-layout-title">Lint Report: 111 warnings</span>
|
||||||
|
Loading…
Reference in New Issue
Block a user