put jingle messages in MAM and parse call log during catchup
This commit is contained in:
parent
9a41d11aed
commit
5b98107e9a
|
@ -733,6 +733,18 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Message findRtpSession(final String sessionId, final int s) {
|
||||||
|
synchronized (this.messages) {
|
||||||
|
for (int i = this.messages.size() - 1; i >= 0; --i) {
|
||||||
|
final Message message = this.messages.get(i);
|
||||||
|
if ((message.getStatus() == s) && (message.getType() == Message.TYPE_RTP_SESSION) && sessionId.equals(message.getRemoteMsgId())) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean possibleDuplicate(final String serverMsgId, final String remoteMsgId) {
|
public boolean possibleDuplicate(final String serverMsgId, final String remoteMsgId) {
|
||||||
if (serverMsgId == null || remoteMsgId == null) {
|
if (serverMsgId == null || remoteMsgId == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1007,7 +1019,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
return UIHelper.getColorForName(getName().toString());
|
return UIHelper.getColorForName(getName().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnMessageFound {
|
public interface OnMessageFound {
|
||||||
void onMessageFound(final Message message);
|
void onMessageFound(final Message message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,245 +24,248 @@ import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
||||||
import rocks.xmpp.addr.Jid;
|
import rocks.xmpp.addr.Jid;
|
||||||
|
|
||||||
public class MessageGenerator extends AbstractGenerator {
|
public class MessageGenerator extends AbstractGenerator {
|
||||||
private static final String OMEMO_FALLBACK_MESSAGE = "I sent you an OMEMO encrypted message but your client doesn’t seem to support that. Find more information on https://conversations.im/omemo";
|
private static final String OMEMO_FALLBACK_MESSAGE = "I sent you an OMEMO encrypted message but your client doesn’t seem to support that. Find more information on https://conversations.im/omemo";
|
||||||
private static final String PGP_FALLBACK_MESSAGE = "I sent you a PGP encrypted message but your client doesn’t seem to support that.";
|
private static final String PGP_FALLBACK_MESSAGE = "I sent you a PGP encrypted message but your client doesn’t seem to support that.";
|
||||||
|
|
||||||
public MessageGenerator(XmppConnectionService service) {
|
public MessageGenerator(XmppConnectionService service) {
|
||||||
super(service);
|
super(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MessagePacket preparePacket(Message message) {
|
private MessagePacket preparePacket(Message message) {
|
||||||
Conversation conversation = (Conversation) message.getConversation();
|
Conversation conversation = (Conversation) message.getConversation();
|
||||||
Account account = conversation.getAccount();
|
Account account = conversation.getAccount();
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
final boolean isWithSelf = conversation.getContact().isSelf();
|
final boolean isWithSelf = conversation.getContact().isSelf();
|
||||||
if (conversation.getMode() == Conversation.MODE_SINGLE) {
|
if (conversation.getMode() == Conversation.MODE_SINGLE) {
|
||||||
packet.setTo(message.getCounterpart());
|
packet.setTo(message.getCounterpart());
|
||||||
packet.setType(MessagePacket.TYPE_CHAT);
|
packet.setType(MessagePacket.TYPE_CHAT);
|
||||||
if (!isWithSelf) {
|
if (!isWithSelf) {
|
||||||
packet.addChild("request", "urn:xmpp:receipts");
|
packet.addChild("request", "urn:xmpp:receipts");
|
||||||
}
|
}
|
||||||
} else if (message.isPrivateMessage()) {
|
} else if (message.isPrivateMessage()) {
|
||||||
packet.setTo(message.getCounterpart());
|
packet.setTo(message.getCounterpart());
|
||||||
packet.setType(MessagePacket.TYPE_CHAT);
|
packet.setType(MessagePacket.TYPE_CHAT);
|
||||||
packet.addChild("x", "http://jabber.org/protocol/muc#user");
|
packet.addChild("x", "http://jabber.org/protocol/muc#user");
|
||||||
packet.addChild("request", "urn:xmpp:receipts");
|
packet.addChild("request", "urn:xmpp:receipts");
|
||||||
} else {
|
} else {
|
||||||
packet.setTo(message.getCounterpart().asBareJid());
|
packet.setTo(message.getCounterpart().asBareJid());
|
||||||
packet.setType(MessagePacket.TYPE_GROUPCHAT);
|
packet.setType(MessagePacket.TYPE_GROUPCHAT);
|
||||||
}
|
}
|
||||||
if (conversation.isSingleOrPrivateAndNonAnonymous() && !message.isPrivateMessage()) {
|
if (conversation.isSingleOrPrivateAndNonAnonymous() && !message.isPrivateMessage()) {
|
||||||
packet.addChild("markable", "urn:xmpp:chat-markers:0");
|
packet.addChild("markable", "urn:xmpp:chat-markers:0");
|
||||||
}
|
}
|
||||||
packet.setFrom(account.getJid());
|
packet.setFrom(account.getJid());
|
||||||
packet.setId(message.getUuid());
|
packet.setId(message.getUuid());
|
||||||
packet.addChild("origin-id", Namespace.STANZA_IDS).setAttribute("id", message.getUuid());
|
packet.addChild("origin-id", Namespace.STANZA_IDS).setAttribute("id", message.getUuid());
|
||||||
if (message.edited()) {
|
if (message.edited()) {
|
||||||
packet.addChild("replace", "urn:xmpp:message-correct:0").setAttribute("id", message.getEditedIdWireFormat());
|
packet.addChild("replace", "urn:xmpp:message-correct:0").setAttribute("id", message.getEditedIdWireFormat());
|
||||||
}
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDelay(MessagePacket packet, long timestamp) {
|
public void addDelay(MessagePacket packet, long timestamp) {
|
||||||
final SimpleDateFormat mDateFormat = new SimpleDateFormat(
|
final SimpleDateFormat mDateFormat = new SimpleDateFormat(
|
||||||
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
|
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
|
||||||
mDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
mDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
Element delay = packet.addChild("delay", "urn:xmpp:delay");
|
Element delay = packet.addChild("delay", "urn:xmpp:delay");
|
||||||
Date date = new Date(timestamp);
|
Date date = new Date(timestamp);
|
||||||
delay.setAttribute("stamp", mDateFormat.format(date));
|
delay.setAttribute("stamp", mDateFormat.format(date));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket generateAxolotlChat(Message message, XmppAxolotlMessage axolotlMessage) {
|
public MessagePacket generateAxolotlChat(Message message, XmppAxolotlMessage axolotlMessage) {
|
||||||
MessagePacket packet = preparePacket(message);
|
MessagePacket packet = preparePacket(message);
|
||||||
if (axolotlMessage == null) {
|
if (axolotlMessage == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
packet.setAxolotlMessage(axolotlMessage.toElement());
|
packet.setAxolotlMessage(axolotlMessage.toElement());
|
||||||
packet.setBody(OMEMO_FALLBACK_MESSAGE);
|
packet.setBody(OMEMO_FALLBACK_MESSAGE);
|
||||||
packet.addChild("store", "urn:xmpp:hints");
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
packet.addChild("encryption", "urn:xmpp:eme:0")
|
packet.addChild("encryption", "urn:xmpp:eme:0")
|
||||||
.setAttribute("name", "OMEMO")
|
.setAttribute("name", "OMEMO")
|
||||||
.setAttribute("namespace", AxolotlService.PEP_PREFIX);
|
.setAttribute("namespace", AxolotlService.PEP_PREFIX);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket generateKeyTransportMessage(Jid to, XmppAxolotlMessage axolotlMessage) {
|
public MessagePacket generateKeyTransportMessage(Jid to, XmppAxolotlMessage axolotlMessage) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(MessagePacket.TYPE_CHAT);
|
packet.setType(MessagePacket.TYPE_CHAT);
|
||||||
packet.setTo(to);
|
packet.setTo(to);
|
||||||
packet.setAxolotlMessage(axolotlMessage.toElement());
|
packet.setAxolotlMessage(axolotlMessage.toElement());
|
||||||
packet.addChild("store", "urn:xmpp:hints");
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket generateChat(Message message) {
|
public MessagePacket generateChat(Message message) {
|
||||||
MessagePacket packet = preparePacket(message);
|
MessagePacket packet = preparePacket(message);
|
||||||
String content;
|
String content;
|
||||||
if (message.hasFileOnRemoteHost()) {
|
if (message.hasFileOnRemoteHost()) {
|
||||||
Message.FileParams fileParams = message.getFileParams();
|
Message.FileParams fileParams = message.getFileParams();
|
||||||
final URL url = fileParams.url;
|
final URL url = fileParams.url;
|
||||||
if (P1S3UrlStreamHandler.PROTOCOL_NAME.equals(url.getProtocol())) {
|
if (P1S3UrlStreamHandler.PROTOCOL_NAME.equals(url.getProtocol())) {
|
||||||
Element x = packet.addChild("x", Namespace.P1_S3_FILE_TRANSFER);
|
Element x = packet.addChild("x", Namespace.P1_S3_FILE_TRANSFER);
|
||||||
final String file = url.getFile();
|
final String file = url.getFile();
|
||||||
x.setAttribute("name", file.charAt(0) == '/' ? file.substring(1) : file);
|
x.setAttribute("name", file.charAt(0) == '/' ? file.substring(1) : file);
|
||||||
x.setAttribute("fileid", url.getHost());
|
x.setAttribute("fileid", url.getHost());
|
||||||
return packet;
|
return packet;
|
||||||
} else {
|
} else {
|
||||||
content = url.toString();
|
content = url.toString();
|
||||||
packet.addChild("x", Namespace.OOB).addChild("url").setContent(content);
|
packet.addChild("x", Namespace.OOB).addChild("url").setContent(content);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content = message.getBody();
|
content = message.getBody();
|
||||||
}
|
}
|
||||||
packet.setBody(content);
|
packet.setBody(content);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket generatePgpChat(Message message) {
|
public MessagePacket generatePgpChat(Message message) {
|
||||||
MessagePacket packet = preparePacket(message);
|
MessagePacket packet = preparePacket(message);
|
||||||
if (message.hasFileOnRemoteHost()) {
|
if (message.hasFileOnRemoteHost()) {
|
||||||
Message.FileParams fileParams = message.getFileParams();
|
Message.FileParams fileParams = message.getFileParams();
|
||||||
final URL url = fileParams.url;
|
final URL url = fileParams.url;
|
||||||
if (P1S3UrlStreamHandler.PROTOCOL_NAME.equals(url.getProtocol())) {
|
if (P1S3UrlStreamHandler.PROTOCOL_NAME.equals(url.getProtocol())) {
|
||||||
Element x = packet.addChild("x", Namespace.P1_S3_FILE_TRANSFER);
|
Element x = packet.addChild("x", Namespace.P1_S3_FILE_TRANSFER);
|
||||||
final String file = url.getFile();
|
final String file = url.getFile();
|
||||||
x.setAttribute("name", file.charAt(0) == '/' ? file.substring(1) : file);
|
x.setAttribute("name", file.charAt(0) == '/' ? file.substring(1) : file);
|
||||||
x.setAttribute("fileid", url.getHost());
|
x.setAttribute("fileid", url.getHost());
|
||||||
} else {
|
} else {
|
||||||
packet.setBody(url.toString());
|
packet.setBody(url.toString());
|
||||||
packet.addChild("x", Namespace.OOB).addChild("url").setContent(url.toString());
|
packet.addChild("x", Namespace.OOB).addChild("url").setContent(url.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Config.supportUnencrypted()) {
|
if (Config.supportUnencrypted()) {
|
||||||
packet.setBody(PGP_FALLBACK_MESSAGE);
|
packet.setBody(PGP_FALLBACK_MESSAGE);
|
||||||
}
|
}
|
||||||
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
|
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
|
||||||
packet.addChild("x", "jabber:x:encrypted").setContent(message.getEncryptedBody());
|
packet.addChild("x", "jabber:x:encrypted").setContent(message.getEncryptedBody());
|
||||||
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
|
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
|
||||||
packet.addChild("x", "jabber:x:encrypted").setContent(message.getBody());
|
packet.addChild("x", "jabber:x:encrypted").setContent(message.getBody());
|
||||||
}
|
}
|
||||||
packet.addChild("encryption", "urn:xmpp:eme:0")
|
packet.addChild("encryption", "urn:xmpp:eme:0")
|
||||||
.setAttribute("namespace", "jabber:x:encrypted");
|
.setAttribute("namespace", "jabber:x:encrypted");
|
||||||
}
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket generateChatState(Conversation conversation) {
|
public MessagePacket generateChatState(Conversation conversation) {
|
||||||
final Account account = conversation.getAccount();
|
final Account account = conversation.getAccount();
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(conversation.getMode() == Conversation.MODE_MULTI ? MessagePacket.TYPE_GROUPCHAT : MessagePacket.TYPE_CHAT);
|
packet.setType(conversation.getMode() == Conversation.MODE_MULTI ? MessagePacket.TYPE_GROUPCHAT : MessagePacket.TYPE_CHAT);
|
||||||
packet.setTo(conversation.getJid().asBareJid());
|
packet.setTo(conversation.getJid().asBareJid());
|
||||||
packet.setFrom(account.getJid());
|
packet.setFrom(account.getJid());
|
||||||
packet.addChild(ChatState.toElement(conversation.getOutgoingChatState()));
|
packet.addChild(ChatState.toElement(conversation.getOutgoingChatState()));
|
||||||
packet.addChild("no-store", "urn:xmpp:hints");
|
packet.addChild("no-store", "urn:xmpp:hints");
|
||||||
packet.addChild("no-storage", "urn:xmpp:hints"); //wrong! don't copy this. Its *store*
|
packet.addChild("no-storage", "urn:xmpp:hints"); //wrong! don't copy this. Its *store*
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket confirm(final Account account, final Jid to, final String id, final Jid counterpart, final boolean groupChat) {
|
public MessagePacket confirm(final Account account, final Jid to, final String id, final Jid counterpart, final boolean groupChat) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(groupChat ? MessagePacket.TYPE_GROUPCHAT : MessagePacket.TYPE_CHAT);
|
packet.setType(groupChat ? MessagePacket.TYPE_GROUPCHAT : MessagePacket.TYPE_CHAT);
|
||||||
packet.setTo(groupChat ? to.asBareJid() : to);
|
packet.setTo(groupChat ? to.asBareJid() : to);
|
||||||
packet.setFrom(account.getJid());
|
packet.setFrom(account.getJid());
|
||||||
Element displayed = packet.addChild("displayed", "urn:xmpp:chat-markers:0");
|
Element displayed = packet.addChild("displayed", "urn:xmpp:chat-markers:0");
|
||||||
displayed.setAttribute("id", id);
|
displayed.setAttribute("id", id);
|
||||||
if (groupChat && counterpart != null) {
|
if (groupChat && counterpart != null) {
|
||||||
displayed.setAttribute("sender", counterpart.toString());
|
displayed.setAttribute("sender", counterpart.toString());
|
||||||
}
|
}
|
||||||
packet.addChild("store", "urn:xmpp:hints");
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket conferenceSubject(Conversation conversation, String subject) {
|
public MessagePacket conferenceSubject(Conversation conversation, String subject) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(MessagePacket.TYPE_GROUPCHAT);
|
packet.setType(MessagePacket.TYPE_GROUPCHAT);
|
||||||
packet.setTo(conversation.getJid().asBareJid());
|
packet.setTo(conversation.getJid().asBareJid());
|
||||||
packet.addChild("subject").setContent(subject);
|
packet.addChild("subject").setContent(subject);
|
||||||
packet.setFrom(conversation.getAccount().getJid().asBareJid());
|
packet.setFrom(conversation.getAccount().getJid().asBareJid());
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket directInvite(final Conversation conversation, final Jid contact) {
|
public MessagePacket directInvite(final Conversation conversation, final Jid contact) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(MessagePacket.TYPE_NORMAL);
|
packet.setType(MessagePacket.TYPE_NORMAL);
|
||||||
packet.setTo(contact);
|
packet.setTo(contact);
|
||||||
packet.setFrom(conversation.getAccount().getJid());
|
packet.setFrom(conversation.getAccount().getJid());
|
||||||
Element x = packet.addChild("x", "jabber:x:conference");
|
Element x = packet.addChild("x", "jabber:x:conference");
|
||||||
x.setAttribute("jid", conversation.getJid().asBareJid().toString());
|
x.setAttribute("jid", conversation.getJid().asBareJid().toString());
|
||||||
String password = conversation.getMucOptions().getPassword();
|
String password = conversation.getMucOptions().getPassword();
|
||||||
if (password != null) {
|
if (password != null) {
|
||||||
x.setAttribute("password", password);
|
x.setAttribute("password", password);
|
||||||
}
|
}
|
||||||
if (contact.isFullJid()) {
|
if (contact.isFullJid()) {
|
||||||
packet.addChild("no-store", "urn:xmpp:hints");
|
packet.addChild("no-store", "urn:xmpp:hints");
|
||||||
packet.addChild("no-copy", "urn:xmpp:hints");
|
packet.addChild("no-copy", "urn:xmpp:hints");
|
||||||
}
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket invite(Conversation conversation, Jid contact) {
|
public MessagePacket invite(Conversation conversation, Jid contact) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setTo(conversation.getJid().asBareJid());
|
packet.setTo(conversation.getJid().asBareJid());
|
||||||
packet.setFrom(conversation.getAccount().getJid());
|
packet.setFrom(conversation.getAccount().getJid());
|
||||||
Element x = new Element("x");
|
Element x = new Element("x");
|
||||||
x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user");
|
x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user");
|
||||||
Element invite = new Element("invite");
|
Element invite = new Element("invite");
|
||||||
invite.setAttribute("to", contact.asBareJid().toString());
|
invite.setAttribute("to", contact.asBareJid().toString());
|
||||||
x.addChild(invite);
|
x.addChild(invite);
|
||||||
packet.addChild(x);
|
packet.addChild(x);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket received(Account account, MessagePacket originalMessage, ArrayList<String> namespaces, int type) {
|
public MessagePacket received(Account account, MessagePacket originalMessage, ArrayList<String> namespaces, int type) {
|
||||||
MessagePacket receivedPacket = new MessagePacket();
|
MessagePacket receivedPacket = new MessagePacket();
|
||||||
receivedPacket.setType(type);
|
receivedPacket.setType(type);
|
||||||
receivedPacket.setTo(originalMessage.getFrom());
|
receivedPacket.setTo(originalMessage.getFrom());
|
||||||
receivedPacket.setFrom(account.getJid());
|
receivedPacket.setFrom(account.getJid());
|
||||||
for (String namespace : namespaces) {
|
for (String namespace : namespaces) {
|
||||||
receivedPacket.addChild("received", namespace).setAttribute("id", originalMessage.getId());
|
receivedPacket.addChild("received", namespace).setAttribute("id", originalMessage.getId());
|
||||||
}
|
}
|
||||||
receivedPacket.addChild("store", "urn:xmpp:hints");
|
receivedPacket.addChild("store", "urn:xmpp:hints");
|
||||||
return receivedPacket;
|
return receivedPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket received(Account account, Jid to, String id) {
|
public MessagePacket received(Account account, Jid to, String id) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setFrom(account.getJid());
|
packet.setFrom(account.getJid());
|
||||||
packet.setTo(to);
|
packet.setTo(to);
|
||||||
packet.addChild("received", "urn:xmpp:receipts").setAttribute("id", id);
|
packet.addChild("received", "urn:xmpp:receipts").setAttribute("id", id);
|
||||||
packet.addChild("store", "urn:xmpp:hints");
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket sessionProposal(final JingleConnectionManager.RtpSessionProposal proposal) {
|
public MessagePacket sessionProposal(final JingleConnectionManager.RtpSessionProposal proposal) {
|
||||||
final MessagePacket packet = new MessagePacket();
|
final MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
|
packet.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
|
||||||
packet.setTo(proposal.with);
|
packet.setTo(proposal.with);
|
||||||
packet.setId(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX +proposal.sessionId);
|
packet.setId(JingleRtpConnection.JINGLE_MESSAGE_PROPOSE_ID_PREFIX + proposal.sessionId);
|
||||||
final Element propose = packet.addChild("propose", Namespace.JINGLE_MESSAGE);
|
final Element propose = packet.addChild("propose", Namespace.JINGLE_MESSAGE);
|
||||||
propose.setAttribute("id", proposal.sessionId);
|
propose.setAttribute("id", proposal.sessionId);
|
||||||
propose.addChild("description", Namespace.JINGLE_APPS_RTP);
|
propose.addChild("description", Namespace.JINGLE_APPS_RTP);
|
||||||
packet.addChild("request", "urn:xmpp:receipts");
|
packet.addChild("request", "urn:xmpp:receipts");
|
||||||
return packet;
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
}
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
public MessagePacket sessionRetract(final JingleConnectionManager.RtpSessionProposal proposal) {
|
public MessagePacket sessionRetract(final JingleConnectionManager.RtpSessionProposal proposal) {
|
||||||
final MessagePacket packet = new MessagePacket();
|
final MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
|
packet.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
|
||||||
packet.setTo(proposal.with);
|
packet.setTo(proposal.with);
|
||||||
final Element propose = packet.addChild("retract", Namespace.JINGLE_MESSAGE);
|
final Element propose = packet.addChild("retract", Namespace.JINGLE_MESSAGE);
|
||||||
propose.setAttribute("id", proposal.sessionId);
|
propose.setAttribute("id", proposal.sessionId);
|
||||||
propose.addChild("description", Namespace.JINGLE_APPS_RTP);
|
propose.addChild("description", Namespace.JINGLE_APPS_RTP);
|
||||||
return packet;
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
}
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
public MessagePacket sessionReject(final Jid with, final String sessionId) {
|
public MessagePacket sessionReject(final Jid with, final String sessionId) {
|
||||||
final MessagePacket packet = new MessagePacket();
|
final MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
|
packet.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
|
||||||
packet.setTo(with);
|
packet.setTo(with);
|
||||||
final Element propose = packet.addChild("reject", Namespace.JINGLE_MESSAGE);
|
final Element propose = packet.addChild("reject", Namespace.JINGLE_MESSAGE);
|
||||||
propose.setAttribute("id", sessionId);
|
propose.setAttribute("id", sessionId);
|
||||||
propose.addChild("description", Namespace.JINGLE_APPS_RTP);
|
propose.addChild("description", Namespace.JINGLE_APPS_RTP);
|
||||||
return packet;
|
packet.addChild("store", "urn:xmpp:hints");
|
||||||
}
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.entities.MucOptions;
|
import eu.siacs.conversations.entities.MucOptions;
|
||||||
import eu.siacs.conversations.entities.ReadByMarker;
|
import eu.siacs.conversations.entities.ReadByMarker;
|
||||||
import eu.siacs.conversations.entities.ReceiptRequest;
|
import eu.siacs.conversations.entities.ReceiptRequest;
|
||||||
|
import eu.siacs.conversations.entities.RtpSessionStatus;
|
||||||
import eu.siacs.conversations.http.HttpConnectionManager;
|
import eu.siacs.conversations.http.HttpConnectionManager;
|
||||||
import eu.siacs.conversations.http.P1S3UrlStreamHandler;
|
import eu.siacs.conversations.http.P1S3UrlStreamHandler;
|
||||||
import eu.siacs.conversations.services.MessageArchiveService;
|
import eu.siacs.conversations.services.MessageArchiveService;
|
||||||
|
@ -73,6 +74,11 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
return safeToExtract ? extractStanzaId(packet, by) : null;
|
return safeToExtract ? extractStanzaId(packet, by) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String extractStanzaId(Account account, Element packet) {
|
||||||
|
final boolean safeToExtract = account.getXmppConnection().getFeatures().stanzaIds();
|
||||||
|
return safeToExtract ? extractStanzaId(packet, account.getJid().asBareJid()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
private static String extractStanzaId(Element packet, Jid by) {
|
private static String extractStanzaId(Element packet, Jid by) {
|
||||||
for (Element child : packet.getChildren()) {
|
for (Element child : packet.getChildren()) {
|
||||||
if (child.getName().equals("stanza-id")
|
if (child.getName().equals("stanza-id")
|
||||||
|
@ -829,17 +835,56 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
if (!isTypeGroupChat) {
|
if (!isTypeGroupChat) {
|
||||||
for (Element child : packet.getChildren()) {
|
for (Element child : packet.getChildren()) {
|
||||||
if (Namespace.JINGLE_MESSAGE.equals(child.getNamespace()) && JINGLE_MESSAGE_ELEMENT_NAMES.contains(child.getName())) {
|
if (Namespace.JINGLE_MESSAGE.equals(child.getNamespace()) && JINGLE_MESSAGE_ELEMENT_NAMES.contains(child.getName())) {
|
||||||
//TODO in this case we probably only want to send receipts for live messages
|
final String action = child.getName();
|
||||||
//as soon as it comes from MAM it is probably too late anyway
|
if (query == null) {
|
||||||
if (!account.getJid().asBareJid().equals(from.asBareJid())) {
|
if (!account.getJid().asBareJid().equals(from.asBareJid())) {
|
||||||
processMessageReceipts(account, packet, query);
|
processMessageReceipts(account, packet, query);
|
||||||
|
}
|
||||||
|
if (serverMsgId == null) {
|
||||||
|
serverMsgId = extractStanzaId(account, packet);
|
||||||
|
}
|
||||||
|
mXmppConnectionService.getJingleConnectionManager().deliverMessage(account, packet.getTo(), packet.getFrom(), child, serverMsgId, timestamp);
|
||||||
|
} else if (query.isCatchup()) {
|
||||||
|
final String sessionId = child.getAttribute("id");
|
||||||
|
if (sessionId == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ("propose".equals(action)) {
|
||||||
|
final Element description = child.findChild("description");
|
||||||
|
final String namespace = description == null ? null : description.getNamespace();
|
||||||
|
if (Namespace.JINGLE_APPS_RTP.equals(namespace)) {
|
||||||
|
final Conversation c = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), false, false);
|
||||||
|
final Message message = new Message(
|
||||||
|
c,
|
||||||
|
status,
|
||||||
|
Message.TYPE_RTP_SESSION,
|
||||||
|
sessionId
|
||||||
|
);
|
||||||
|
message.setServerMsgId(serverMsgId);
|
||||||
|
message.setTime(timestamp);
|
||||||
|
message.setBody(new RtpSessionStatus(false, 0).toString());
|
||||||
|
c.add(message);
|
||||||
|
mXmppConnectionService.databaseBackend.createMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ("proceed".equals(action)) {
|
||||||
|
//status needs to be flipped to find the original propose
|
||||||
|
final Conversation c = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), false, false);
|
||||||
|
final int s = packet.fromAccount(account) ? Message.STATUS_RECEIVED : Message.STATUS_SEND;
|
||||||
|
final Message message = c.findRtpSession(sessionId, s);
|
||||||
|
if (message != null) {
|
||||||
|
message.setBody(new RtpSessionStatus(true, 0).toString());
|
||||||
|
if (serverMsgId != null) {
|
||||||
|
message.setServerMsgId(serverMsgId);
|
||||||
|
}
|
||||||
|
message.setTime(timestamp);
|
||||||
|
mXmppConnectionService.updateMessage(message, true);
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, "unable to find original rtp session message for received propose");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//TODO only live propose messages should get processed that way; however we may want to deliver 'accept' and 'reject' to stop ringing
|
|
||||||
mXmppConnectionService.getJingleConnectionManager().deliverMessage(account, packet.getTo(), packet.getFrom(), child, serverMsgId, timestamp);
|
|
||||||
|
|
||||||
|
|
||||||
//TODO for queries we might want to process 'propose' and 'proceed'
|
|
||||||
//TODO propose will trigger a 'missed call' entry; 'proceed' might update that to a non missed call
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -494,7 +494,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
if (from.equals(id.with)) {
|
if (from.equals(id.with)) {
|
||||||
if (transition(State.RETRACTED)) {
|
if (transition(State.RETRACTED)) {
|
||||||
xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
|
xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
|
||||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": session with " + id.with + " has been retracted");
|
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": session with " + id.with + " has been retracted (serverMsgId="+serverMsgId+")");
|
||||||
if (serverMsgId != null) {
|
if (serverMsgId != null) {
|
||||||
this.message.setServerMsgId(serverMsgId);
|
this.message.setServerMsgId(serverMsgId);
|
||||||
}
|
}
|
||||||
|
@ -776,7 +776,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
messagePacket.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
|
messagePacket.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those
|
||||||
messagePacket.setTo(to);
|
messagePacket.setTo(to);
|
||||||
messagePacket.addChild(action, Namespace.JINGLE_MESSAGE).setAttribute("id", id.sessionId);
|
messagePacket.addChild(action, Namespace.JINGLE_MESSAGE).setAttribute("id", id.sessionId);
|
||||||
Log.d(Config.LOGTAG, messagePacket.toString());
|
messagePacket.addChild("store", "urn:xmpp:hints");
|
||||||
xmppConnectionService.sendMessagePacket(id.account, messagePacket);
|
xmppConnectionService.sendMessagePacket(id.account, messagePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue