create temporary RtpSessionPropsoal as placeholder before we can create actual session
This commit is contained in:
parent
e2e4390d51
commit
3b857e6894
|
@ -18,6 +18,7 @@ import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xml.Namespace;
|
import eu.siacs.conversations.xml.Namespace;
|
||||||
import eu.siacs.conversations.xmpp.chatstate.ChatState;
|
import eu.siacs.conversations.xmpp.chatstate.ChatState;
|
||||||
|
import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
||||||
import rocks.xmpp.addr.Jid;
|
import rocks.xmpp.addr.Jid;
|
||||||
|
|
||||||
|
@ -231,4 +232,13 @@ public class MessageGenerator extends AbstractGenerator {
|
||||||
packet.addChild("store", "urn:xmpp:hints");
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MessagePacket sessionProposal(JingleConnectionManager.RtpSessionProposal proposal) {
|
||||||
|
final MessagePacket packet = new MessagePacket();
|
||||||
|
packet.setTo(proposal.with);
|
||||||
|
final Element propose = packet.addChild("propose", Namespace.JINGLE_MESSAGE);
|
||||||
|
propose.setAttribute("id", proposal.sessionId);
|
||||||
|
propose.addChild("description", Namespace.JINGLE_APPS_RTP);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
private OnClickListener acceptJoin = new OnClickListener() {
|
private OnClickListener acceptJoin = new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
conversation.setAttribute("accept_non_anonymous",true);
|
conversation.setAttribute("accept_non_anonymous", true);
|
||||||
activity.xmppConnectionService.updateConversation(conversation);
|
activity.xmppConnectionService.updateConversation(conversation);
|
||||||
activity.xmppConnectionService.joinMuc(conversation);
|
activity.xmppConnectionService.joinMuc(conversation);
|
||||||
}
|
}
|
||||||
|
@ -1127,7 +1127,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
showErrorMessage.setVisible(true);
|
showErrorMessage.setVisible(true);
|
||||||
}
|
}
|
||||||
final String mime = m.isFileOrImage() ? m.getMimeType() : null;
|
final String mime = m.isFileOrImage() ? m.getMimeType() : null;
|
||||||
if ((m.isGeoUri() && GeoHelper.openInOsmAnd(getActivity(),m)) || (mime != null && mime.startsWith("audio/"))) {
|
if ((m.isGeoUri() && GeoHelper.openInOsmAnd(getActivity(), m)) || (mime != null && mime.startsWith("audio/"))) {
|
||||||
openWith.setVisible(true);
|
openWith.setVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1232,12 +1232,20 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
BlockContactDialog.show((XmppActivity) activity, conversation);
|
BlockContactDialog.show((XmppActivity) activity, conversation);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case R.id.action_call:
|
||||||
|
triggerRtpSession();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void triggerRtpSession() {
|
||||||
|
final Contact contact = conversation.getContact();
|
||||||
|
activity.xmppConnectionService.getJingleConnectionManager().proposeJingleRtpSession(conversation.getAccount(), contact);
|
||||||
|
}
|
||||||
|
|
||||||
private void handleAttachmentSelection(MenuItem item) {
|
private void handleAttachmentSelection(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.attach_choose_picture:
|
case R.id.attach_choose_picture:
|
||||||
|
@ -1431,7 +1439,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
} else if (message.treatAsDownloadable() || message.hasFileOnRemoteHost() || MessageUtils.unInitiatedButKnownSize(message)) {
|
} else if (message.treatAsDownloadable() || message.hasFileOnRemoteHost() || MessageUtils.unInitiatedButKnownSize(message)) {
|
||||||
createNewConnection(message);
|
createNewConnection(message);
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG,message.getConversation().getAccount()+": unable to start downloadable");
|
Log.d(Config.LOGTAG, message.getConversation().getAccount() + ": unable to start downloadable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1621,7 +1629,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
|
|
||||||
private void openWith(final Message message) {
|
private void openWith(final Message message) {
|
||||||
if (message.isGeoUri()) {
|
if (message.isGeoUri()) {
|
||||||
GeoHelper.view(getActivity(),message);
|
GeoHelper.view(getActivity(), message);
|
||||||
} else {
|
} else {
|
||||||
final DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message);
|
final DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message);
|
||||||
ViewUtil.view(activity, file);
|
ViewUtil.view(activity, file);
|
||||||
|
@ -1641,8 +1649,8 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
}
|
}
|
||||||
builder.setMessage(displayError);
|
builder.setMessage(displayError);
|
||||||
builder.setNegativeButton(R.string.copy_to_clipboard, (dialog, which) -> {
|
builder.setNegativeButton(R.string.copy_to_clipboard, (dialog, which) -> {
|
||||||
activity.copyTextToClipboard(displayError,R.string.error_message);
|
activity.copyTextToClipboard(displayError, R.string.error_message);
|
||||||
Toast.makeText(activity,R.string.error_message_copied_to_clipboard, Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, R.string.error_message_copied_to_clipboard, Toast.LENGTH_SHORT).show();
|
||||||
});
|
});
|
||||||
builder.setPositiveButton(R.string.confirm, null);
|
builder.setPositiveButton(R.string.confirm, null);
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
|
@ -2744,10 +2752,10 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
Log.e(Config.LOGTAG, "cleared pending photo uri");
|
Log.e(Config.LOGTAG, "cleared pending photo uri");
|
||||||
}
|
}
|
||||||
if (pendingConversationsUuid.clear()) {
|
if (pendingConversationsUuid.clear()) {
|
||||||
Log.e(Config.LOGTAG,"cleared pending conversations uuid");
|
Log.e(Config.LOGTAG, "cleared pending conversations uuid");
|
||||||
}
|
}
|
||||||
if (pendingMediaPreviews.clear()) {
|
if (pendingMediaPreviews.clear()) {
|
||||||
Log.e(Config.LOGTAG,"cleared pending media previews");
|
Log.e(Config.LOGTAG, "cleared pending media previews");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2765,7 +2773,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
}
|
}
|
||||||
final PopupMenu popupMenu = new PopupMenu(getActivity(), v);
|
final PopupMenu popupMenu = new PopupMenu(getActivity(), v);
|
||||||
final Contact contact = message.getContact();
|
final Contact contact = message.getContact();
|
||||||
if (message.getStatus() <= Message.STATUS_RECEIVED && (contact == null || !contact.isSelf())) {
|
if (message.getStatus() <= Message.STATUS_RECEIVED && (contact == null || !contact.isSelf())) {
|
||||||
if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
|
if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
|
||||||
final Jid cp = message.getCounterpart();
|
final Jid cp = message.getCounterpart();
|
||||||
if (cp == null || cp.isBareJid()) {
|
if (cp == null || cp.isBareJid()) {
|
||||||
|
|
|
@ -2,15 +2,19 @@ package eu.siacs.conversations.xmpp.jingle;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.entities.Transferable;
|
import eu.siacs.conversations.entities.Transferable;
|
||||||
import eu.siacs.conversations.services.AbstractConnectionManager;
|
import eu.siacs.conversations.services.AbstractConnectionManager;
|
||||||
|
@ -22,10 +26,12 @@ import eu.siacs.conversations.xmpp.jingle.stanzas.Content;
|
||||||
import eu.siacs.conversations.xmpp.jingle.stanzas.FileTransferDescription;
|
import eu.siacs.conversations.xmpp.jingle.stanzas.FileTransferDescription;
|
||||||
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
|
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||||
|
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
||||||
import rocks.xmpp.addr.Jid;
|
import rocks.xmpp.addr.Jid;
|
||||||
|
|
||||||
public class JingleConnectionManager extends AbstractConnectionManager {
|
public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
private Map<AbstractJingleConnection.Id, AbstractJingleConnection> connections = new ConcurrentHashMap<>();
|
private final Set<RtpSessionProposal> rtpSessionProposals = new HashSet<>();
|
||||||
|
private final Map<AbstractJingleConnection.Id, AbstractJingleConnection> connections = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private HashMap<Jid, JingleCandidate> primaryCandidates = new HashMap<>();
|
private HashMap<Jid, JingleCandidate> primaryCandidates = new HashMap<>();
|
||||||
|
|
||||||
|
@ -95,6 +101,22 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to react to proposed " + namespace + " session");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to react to proposed " + namespace + " session");
|
||||||
}
|
}
|
||||||
|
} else if ("proceed".equals(message.getName())) {
|
||||||
|
if (!with.equals(from)) {
|
||||||
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": ignore carbon copied proceed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final RtpSessionProposal proposal = new RtpSessionProposal(account, with.asBareJid(), sessionId);
|
||||||
|
synchronized (rtpSessionProposals) {
|
||||||
|
if (rtpSessionProposals.remove(proposal)) {
|
||||||
|
final JingleRtpConnection rtpConnection = new JingleRtpConnection(this, id, account.getJid());
|
||||||
|
this.connections.put(id, rtpConnection);
|
||||||
|
rtpConnection.transitionOrThrow(AbstractJingleConnection.State.PROPOSED);
|
||||||
|
rtpConnection.deliveryMessage(from, message);
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": no rtp session proposal found for " + with);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": retrieved out of order jingle message");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": retrieved out of order jingle message");
|
||||||
}
|
}
|
||||||
|
@ -165,6 +187,16 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void proposeJingleRtpSession(final Account account, final Contact contact) {
|
||||||
|
final RtpSessionProposal proposal = RtpSessionProposal.of(account, contact.getJid().asBareJid());
|
||||||
|
synchronized (this.rtpSessionProposals) {
|
||||||
|
this.rtpSessionProposals.add(proposal);
|
||||||
|
final MessagePacket messagePacket = mXmppConnectionService.getMessageGenerator().sessionProposal(proposal);
|
||||||
|
Log.d(Config.LOGTAG,messagePacket.toString());
|
||||||
|
mXmppConnectionService.sendMessagePacket(account, messagePacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static String nextRandomId() {
|
static String nextRandomId() {
|
||||||
return UUID.randomUUID().toString();
|
return UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
@ -211,4 +243,35 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class RtpSessionProposal {
|
||||||
|
private final Account account;
|
||||||
|
public final Jid with;
|
||||||
|
public final String sessionId;
|
||||||
|
|
||||||
|
private RtpSessionProposal(Account account, Jid with, String sessionId) {
|
||||||
|
this.account = account;
|
||||||
|
this.with = with;
|
||||||
|
this.sessionId = sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RtpSessionProposal of(Account account, Jid with) {
|
||||||
|
return new RtpSessionProposal(account, with, UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
RtpSessionProposal proposal = (RtpSessionProposal) o;
|
||||||
|
return Objects.equal(account.getJid(), proposal.account.getJid()) &&
|
||||||
|
Objects.equal(with, proposal.with) &&
|
||||||
|
Objects.equal(sessionId, proposal.sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(account.getJid(), with, sessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
||||||
private void receiveProceed(final Jid from, final Element proceed) {
|
private void receiveProceed(final Jid from, final Element proceed) {
|
||||||
if (from.equals(id.with)) {
|
if (from.equals(id.with)) {
|
||||||
if (isInitiator()) {
|
if (isInitiator()) {
|
||||||
if (transition(State.SESSION_INITIALIZED)) {
|
if (transition(State.PROCEED)) {
|
||||||
this.sendSessionInitiate();
|
this.sendSessionInitiate();
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, String.format("%s: ignoring proceed because already in %s", id.account.getJid().asBareJid(), this.state));
|
Log.d(Config.LOGTAG, String.format("%s: ignoring proceed because already in %s", id.account.getJid().asBareJid(), this.state));
|
||||||
|
@ -142,7 +142,7 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendSessionInitiate() {
|
private void sendSessionInitiate() {
|
||||||
|
Log.d(Config.LOGTAG,id.account.getJid().asBareJid()+": sending session-initiate");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendSessionAccept() {
|
private void sendSessionAccept() {
|
||||||
|
@ -167,7 +167,7 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
||||||
final MessagePacket messagePacket = new MessagePacket();
|
final MessagePacket messagePacket = new MessagePacket();
|
||||||
messagePacket.setTo(id.with);
|
messagePacket.setTo(id.with);
|
||||||
//Note that Movim needs 'accept', correct is 'proceed' https://github.com/movim/movim/issues/916
|
//Note that Movim needs 'accept', correct is 'proceed' https://github.com/movim/movim/issues/916
|
||||||
messagePacket.addChild("accept", Namespace.JINGLE_MESSAGE).setAttribute("id", id.sessionId);
|
messagePacket.addChild("proceed", Namespace.JINGLE_MESSAGE).setAttribute("id", id.sessionId);
|
||||||
Log.d(Config.LOGTAG, messagePacket.toString());
|
Log.d(Config.LOGTAG, messagePacket.toString());
|
||||||
xmppConnectionService.sendMessagePacket(id.account, messagePacket);
|
xmppConnectionService.sendMessagePacket(id.account, messagePacket);
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transitionOrThrow(final State target) {
|
public void transitionOrThrow(final State target) {
|
||||||
if (!transition(target)) {
|
if (!transition(target)) {
|
||||||
throw new IllegalStateException(String.format("Unable to transition from %s to %s", this.state, target));
|
throw new IllegalStateException(String.format("Unable to transition from %s to %s", this.state, target));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue