diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index c34ad1c4a..e692787a3 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -39,10 +39,43 @@ import rocks.xmpp.addr.Jid; public class MessageParser extends AbstractParser implements OnMessagePacketReceived { + private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH); + public MessageParser(XmppConnectionService service) { super(service); } + private static String extractStanzaId(Element packet, boolean isTypeGroupChat, Conversation conversation) { + final Jid by; + final boolean safeToExtract; + if (isTypeGroupChat) { + by = conversation.getJid().asBareJid(); + safeToExtract = conversation.getMucOptions().hasFeature(Namespace.STANZA_IDS); + } else { + Account account = conversation.getAccount(); + by = account.getJid().asBareJid(); + safeToExtract = account.getXmppConnection().getFeatures().stanzaIds(); + } + return safeToExtract ? extractStanzaId(packet, by) : null; + } + + private static String extractStanzaId(Element packet, Jid by) { + for (Element child : packet.getChildren()) { + if (child.getName().equals("stanza-id") + && Namespace.STANZA_IDS.equals(child.getNamespace()) + && by.equals(child.getAttributeAsJid("by"))) { + return child.getAttribute("id"); + } + } + return null; + } + + private static Jid getTrueCounterpart(Element mucUserElement, Jid fallback) { + final Element item = mucUserElement == null ? null : mucUserElement.findChild("item"); + Jid result = item == null ? null : item.getAttributeAsJid("jid"); + return result != null ? result : fallback; + } + private boolean extractChatState(Conversation c, final boolean isTypeGroupChat, final MessagePacket packet) { ChatState state = ChatState.parse(packet); if (state != null && c != null) { @@ -89,38 +122,12 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece return finishedMessage; } } else { - Log.d(Config.LOGTAG,conversation.getAccount().getJid().asBareJid()+": received OMEMO key transport message"); + Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": received OMEMO key transport message"); service.processReceivingKeyTransportMessage(xmppAxolotlMessage, postpone); } return null; } - private class Invite { - final Jid jid; - final String password; - final Contact inviter; - - Invite(Jid jid, String password, Contact inviter) { - this.jid = jid; - this.password = password; - this.inviter = inviter; - } - - public boolean execute(Account account) { - if (jid != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid, true, false); - if (!conversation.getMucOptions().online()) { - conversation.getMucOptions().setPassword(password); - mXmppConnectionService.databaseBackend.updateConversation(conversation); - mXmppConnectionService.joinMuc(conversation, inviter != null && inviter.mutualPresenceSubscription()); - mXmppConnectionService.updateConversationUi(); - } - return true; - } - return false; - } - } - private Invite extractInvite(Account account, Element message) { Element x = message.findChild("x", "http://jabber.org/protocol/muc#user"); if (x != null) { @@ -142,31 +149,6 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece return null; } - private static String extractStanzaId(Element packet, boolean isTypeGroupChat, Conversation conversation) { - final Jid by; - final boolean safeToExtract; - if (isTypeGroupChat) { - by = conversation.getJid().asBareJid(); - safeToExtract = conversation.getMucOptions().hasFeature(Namespace.STANZA_IDS); - } else { - Account account = conversation.getAccount(); - by = account.getJid().asBareJid(); - safeToExtract = account.getXmppConnection().getFeatures().stanzaIds(); - } - return safeToExtract ? extractStanzaId(packet, by) : null; - } - - private static String extractStanzaId(Element packet, Jid by) { - for (Element child : packet.getChildren()) { - if (child.getName().equals("stanza-id") - && Namespace.STANZA_IDS.equals(child.getNamespace()) - && by.equals(child.getAttributeAsJid("by"))) { - return child.getAttribute("id"); - } - } - return null; - } - private void parseEvent(final Element event, final Jid from, final Account account) { Element items = event.findChild("items"); String node = items == null ? null : items.getAttribute("node"); @@ -303,7 +285,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; if (query != null && !query.muc() && isTypeGroupChat) { - Log.e(Config.LOGTAG,account.getJid().asBareJid()+": received groupchat ("+from+") message on regular MAM request. skipping"); + Log.e(Config.LOGTAG, account.getJid().asBareJid() + ": received groupchat (" + from + ") message on regular MAM request. skipping"); return; } boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status"); @@ -342,7 +324,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece return; } status = Message.STATUS_RECEIVED; - if (remoteMsgId != null && conversation.findMessageWithRemoteId(remoteMsgId,counterpart) != null) { + if (remoteMsgId != null && conversation.findMessageWithRemoteId(remoteMsgId, counterpart) != null) { return; } } @@ -392,10 +374,10 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece message = parseAxolotlChat(axolotlEncrypted, origin, conversation, status, query != null); } else { Message trial = null; - for(Jid fallback : fallbacksBySourceId) { + for (Jid fallback : fallbacksBySourceId) { trial = parseAxolotlChat(axolotlEncrypted, fallback, conversation, status, query != null); if (trial != null) { - Log.d(Config.LOGTAG,account.getJid().asBareJid()+": decoded muc message using fallback"); + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": decoded muc message using fallback"); origin = fallback; break; } @@ -403,7 +385,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece message = trial; } if (message == null) { - if (query == null && extractChatState(mXmppConnectionService.find(account, counterpart.asBareJid()), isTypeGroupChat, packet)) { + if (query == null && extractChatState(mXmppConnectionService.find(account, counterpart.asBareJid()), isTypeGroupChat, packet)) { mXmppConnectionService.updateConversationUi(); } if (query != null && status == Message.STATUS_SEND && remoteMsgId != null) { @@ -411,7 +393,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece if (previouslySent != null && previouslySent.getServerMsgId() == null && serverMsgId != null) { previouslySent.setServerMsgId(serverMsgId); mXmppConnectionService.databaseBackend.updateMessage(previouslySent); - Log.d(Config.LOGTAG,account.getJid().asBareJid()+": encountered previously sent OMEMO message without serverId. updating..."); + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": encountered previously sent OMEMO message without serverId. updating..."); } } return; @@ -521,7 +503,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece boolean checkForDuplicates = (isTypeGroupChat && packet.hasChild("delay", "urn:xmpp:delay")) || message.getType() == Message.TYPE_PRIVATE || message.getServerMsgId() != null; - if (checkForDuplicates ) { + if (checkForDuplicates) { final Message duplicate = conversation.findDuplicateMessage(message); if (duplicate != null) { final boolean serverMsgIdUpdated; @@ -535,13 +517,13 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece } else { serverMsgIdUpdated = false; } - Log.d(Config.LOGTAG, "skipping duplicate message with " + message.getCounterpart()+". serverMsgIdUpdated="+Boolean.toString(serverMsgIdUpdated)); + Log.d(Config.LOGTAG, "skipping duplicate message with " + message.getCounterpart() + ". serverMsgIdUpdated=" + Boolean.toString(serverMsgIdUpdated)); return; } } if (query != null && query.getPagingOrder() == MessageArchiveService.PagingOrder.REVERSE) { - conversation.prepend(query.getActualInThisQuery(),message); + conversation.prepend(query.getActualInThisQuery(), message); } else { conversation.add(message); } @@ -610,7 +592,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece try { final XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(axolotlEncrypted, origin.asBareJid()); account.getAxolotlService().processReceivingKeyTransportMessage(xmppAxolotlMessage, query != null); - Log.d(Config.LOGTAG,account.getJid().asBareJid()+": omemo key transport message received from "+origin); + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": omemo key transport message received from " + origin); } catch (Exception e) { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": invalid omemo key transport message received " + e.getMessage()); return; @@ -692,7 +674,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece String id = received.getAttribute("id"); if (packet.fromAccount(account)) { if (query != null && id != null && packet.getTo() != null) { - query.removePendingReceiptRequest(new ReceiptRequest(packet.getTo(),id)); + query.removePendingReceiptRequest(new ReceiptRequest(packet.getTo(), id)); } } else { mXmppConnectionService.markMessage(account, from.asBareJid(), received.getAttribute("id"), Message.STATUS_SEND_RECEIVED); @@ -716,7 +698,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece if (!message.isRead() && (query == null || query.isCatchup())) { //checking if message is unread fixes race conditions with reflections mXmppConnectionService.markRead(conversation); } - } else if (!counterpart.isBareJid() && trueJid != null){ + } else if (!counterpart.isBareJid() && trueJid != null) { ReadByMarker readByMarker = ReadByMarker.from(counterpart, trueJid); if (message.addReadByMarker(readByMarker)) { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": added read by (" + readByMarker.getRealJid() + ") to message '" + message.getBody() + "'"); @@ -761,12 +743,6 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece } } - private static Jid getTrueCounterpart(Element mucUserElement, Jid fallback) { - final Element item = mucUserElement == null ? null : mucUserElement.findChild("item"); - Jid result = item == null ? null : item.getAttributeAsJid("jid"); - return result != null ? result : fallback; - } - private void processMessageReceipts(Account account, MessagePacket packet, MessageArchiveService.Query query) { final boolean markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); final boolean request = packet.hasChild("request", "urn:xmpp:receipts"); @@ -787,16 +763,40 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece } } else { //just catchup?? if (request) { - query.addPendingReceiptRequest(new ReceiptRequest(packet.getFrom(),packet.getId())); + query.addPendingReceiptRequest(new ReceiptRequest(packet.getFrom(), packet.getId())); } } } - private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH); - private void activateGracePeriod(Account account) { long duration = mXmppConnectionService.getLongPreference("grace_period_length", R.integer.grace_period) * 1000; Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": activating grace period till " + TIME_FORMAT.format(new Date(System.currentTimeMillis() + duration))); account.activateGracePeriod(duration); } + + private class Invite { + final Jid jid; + final String password; + final Contact inviter; + + Invite(Jid jid, String password, Contact inviter) { + this.jid = jid; + this.password = password; + this.inviter = inviter; + } + + public boolean execute(Account account) { + if (jid != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid, true, false); + if (!conversation.getMucOptions().online()) { + conversation.getMucOptions().setPassword(password); + mXmppConnectionService.databaseBackend.updateConversation(conversation); + mXmppConnectionService.joinMuc(conversation, inviter != null && inviter.mutualPresenceSubscription()); + mXmppConnectionService.updateConversationUi(); + } + return true; + } + return false; + } + } }