From 71dbbbd2674fe7651c1444adc1ac760beeccb650 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Mon, 9 Jul 2018 22:24:03 +0200 Subject: support mam:1 --- .../de/pixart/messenger/entities/MucOptions.java | 14 ++-- .../de/pixart/messenger/generator/IqGenerator.java | 4 +- .../de/pixart/messenger/parser/MessageParser.java | 7 +- .../messenger/services/MessageArchiveService.java | 83 +++++++++++++++++++--- .../messenger/services/XmppConnectionService.java | 6 +- .../java/de/pixart/messenger/utils/Namespace.java | 2 - .../de/pixart/messenger/xmpp/XmppConnection.java | 11 +-- 7 files changed, 95 insertions(+), 32 deletions(-) (limited to 'src/main/java/de/pixart') diff --git a/src/main/java/de/pixart/messenger/entities/MucOptions.java b/src/main/java/de/pixart/messenger/entities/MucOptions.java index 47ca622fc..1b60a8c97 100644 --- a/src/main/java/de/pixart/messenger/entities/MucOptions.java +++ b/src/main/java/de/pixart/messenger/entities/MucOptions.java @@ -11,8 +11,8 @@ import java.util.Set; import de.pixart.messenger.Config; import de.pixart.messenger.R; +import de.pixart.messenger.services.MessageArchiveService; import de.pixart.messenger.utils.JidHelper; -import de.pixart.messenger.utils.Namespace; import de.pixart.messenger.utils.UIHelper; import de.pixart.messenger.xmpp.chatstate.ChatState; import de.pixart.messenger.xmpp.forms.Data; @@ -66,6 +66,10 @@ public class MucOptions { } } + public boolean mamSupport() { + return MessageArchiveService.Version.has(getFeatures()); + } + public enum Affiliation { OWNER("owner", 4, R.string.owner), ADMIN("admin", 3, R.string.admin), @@ -455,12 +459,8 @@ public class MucOptions { return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, false); } - public boolean mamSupport() { - return hasFeature(Namespace.MAM) || hasFeature(Namespace.MAM_LEGACY); - } - - public boolean mamLegacy() { - return hasFeature(Namespace.MAM_LEGACY) && !hasFeature(Namespace.MAM); + public List getFeatures() { + return this.serviceDiscoveryResult != null ? this.serviceDiscoveryResult.features : Collections.emptyList(); } public boolean nonanonymous() { diff --git a/src/main/java/de/pixart/messenger/generator/IqGenerator.java b/src/main/java/de/pixart/messenger/generator/IqGenerator.java index eab087975..84e8d1a05 100644 --- a/src/main/java/de/pixart/messenger/generator/IqGenerator.java +++ b/src/main/java/de/pixart/messenger/generator/IqGenerator.java @@ -248,10 +248,10 @@ public class IqGenerator extends AbstractGenerator { public IqPacket queryMessageArchiveManagement(final MessageArchiveService.Query mam) { final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); - final Element query = packet.query(mam.isLegacy() ? Namespace.MAM_LEGACY : Namespace.MAM); + final Element query = packet.query(mam.version.namespace); query.setAttribute("queryid", mam.getQueryId()); final Data data = new Data(); - data.setFormType(mam.isLegacy() ? Namespace.MAM_LEGACY : Namespace.MAM); + data.setFormType(mam.version.namespace); if (mam.muc()) { packet.setTo(mam.getWith()); } else if (mam.getWith() != null) { diff --git a/src/main/java/de/pixart/messenger/parser/MessageParser.java b/src/main/java/de/pixart/messenger/parser/MessageParser.java index 2f8d19810..e86758fd7 100644 --- a/src/main/java/de/pixart/messenger/parser/MessageParser.java +++ b/src/main/java/de/pixart/messenger/parser/MessageParser.java @@ -338,16 +338,15 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece final boolean isForwarded; boolean isCarbon = false; String serverMsgId = null; - final Element fin = original.findChild("fin", Namespace.MAM_LEGACY); + final Element fin = original.findChild("fin", MessageArchiveService.Version.MAM_0.namespace); if (fin != null) { mXmppConnectionService.getMessageArchiveService().processFinLegacy(fin, original.getFrom()); return; } - final boolean mamLegacy = original.hasChild("result", Namespace.MAM_LEGACY); - final Element result = original.findChild("result", mamLegacy ? Namespace.MAM_LEGACY : Namespace.MAM); + final Element result = MessageArchiveService.Version.findResult(original); final MessageArchiveService.Query query = result == null ? null : mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); if (query != null && query.validFrom(original.getFrom())) { - Pair f = original.getForwardedMessagePacket("result", mamLegacy ? Namespace.MAM_LEGACY : Namespace.MAM); + Pair f = original.getForwardedMessagePacket("result", query.version.namespace); if (f == null) { return; } diff --git a/src/main/java/de/pixart/messenger/services/MessageArchiveService.java b/src/main/java/de/pixart/messenger/services/MessageArchiveService.java index df376ab73..d9394d4dc 100644 --- a/src/main/java/de/pixart/messenger/services/MessageArchiveService.java +++ b/src/main/java/de/pixart/messenger/services/MessageArchiveService.java @@ -15,11 +15,11 @@ import de.pixart.messenger.entities.Conversation; import de.pixart.messenger.entities.Conversational; import de.pixart.messenger.entities.ReceiptRequest; import de.pixart.messenger.generator.AbstractGenerator; -import de.pixart.messenger.utils.Namespace; import de.pixart.messenger.xml.Element; import de.pixart.messenger.xmpp.OnAdvancedStreamFeaturesLoaded; import de.pixart.messenger.xmpp.mam.MamReference; import de.pixart.messenger.xmpp.stanzas.IqPacket; +import de.pixart.messenger.xmpp.stanzas.MessagePacket; import rocks.xmpp.addr.Jid; public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { @@ -29,6 +29,68 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { private final HashSet queries = new HashSet<>(); private final ArrayList pendingQueries = new ArrayList<>(); + public enum Version { + MAM_0("urn:xmpp:mam:0", true), + MAM_1("urn:xmpp:mam:1", false), + MAM_2("urn:xmpp:mam:2", false); + + public final boolean legacy; + public final String namespace; + + Version(String namespace, boolean legacy) { + this.namespace = namespace; + this.legacy = legacy; + } + + public static Version get(Account account) { + return get(account, null); + } + + public static Version get(Account account, Conversation conversation) { + if (conversation == null || conversation.getMode() == Conversation.MODE_SINGLE) { + return get(account.getXmppConnection().getFeatures().getAccountFeatures()); + } else { + return get(conversation.getMucOptions().getFeatures()); + } + } + + private static Version get(List features) { + final Version[] values = values(); + for (int i = values.length - 1; i >= 0; --i) { + for (String feature : features) { + if (values[i].namespace.equals(feature)) { + return values[i]; + } + } + } + return MAM_0; + } + + public static boolean has(List features) { + for (String feature : features) { + for (Version version : values()) { + if (version.namespace.equals(feature)) { + return true; + } + } + } + return false; + } + + public static Element findResult(MessagePacket packet) { + for (Version version : values()) { + Element result = packet.findChild("result", version.namespace); + if (result != null) { + return result; + } + } + return null; + } + + } + + ; + MessageArchiveService(final XmppConnectionService service) { this.mXmppConnectionService = service; } @@ -168,7 +230,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { Log.d(Config.LOGTAG, account.getJid().asBareJid().toString() + ": running mam query " + query.toString()); IqPacket packet = this.mXmppConnectionService.getIqGenerator().queryMessageArchiveManagement(query); this.mXmppConnectionService.sendIqPacket(account, packet, (a, p) -> { - Element fin = p.findChild("fin", Namespace.MAM); + Element fin = p.findChild("fin", query.version.namespace); if (p.getType() == IqPacket.TYPE.TIMEOUT) { synchronized (MessageArchiveService.this.queries) { MessageArchiveService.this.queries.remove(query); @@ -389,16 +451,21 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { private PagingOrder pagingOrder = PagingOrder.NORMAL; private XmppConnectionService.OnMoreMessagesLoaded callback = null; private boolean catchup = true; + public final Version version; Query(Conversation conversation, MamReference start, long end, boolean catchup) { - this(conversation.getAccount(), catchup ? start : start.timeOnly(), end); + this(conversation.getAccount(), Version.get(conversation.getAccount(), conversation), catchup ? start : start.timeOnly(), end); this.conversation = conversation; this.pagingOrder = catchup ? PagingOrder.NORMAL : PagingOrder.REVERSE; this.catchup = catchup; } Query(Account account, MamReference start, long end) { + this(account, Version.get(account), start, end); + } + + Query(Account account, Version version, MamReference start, long end) { this.account = account; if (start.getReference() != null) { this.reference = start.getReference(); @@ -407,10 +474,11 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { } this.end = end; this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32); + this.version = version; } private Query page(String reference) { - Query query = new Query(this.account, new MamReference(this.start, reference), this.end); + Query query = new Query(this.account, this.version, new MamReference(this.start, reference), this.end); query.conversation = conversation; query.totalCount = totalCount; query.actualCount = actualCount; @@ -432,11 +500,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { } public boolean isLegacy() { - if (conversation == null || conversation.getMode() == Conversation.MODE_SINGLE) { - return account.getXmppConnection().getFeatures().mamLegacy(); - } else { - return conversation.getMucOptions().mamLegacy(); - } + return version.legacy; } public boolean safeToExtractTrueCounterpart() { @@ -569,6 +633,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { builder.append(this.reference); } builder.append(", catchup=").append(Boolean.toString(catchup)); + builder.append(", ns=").append(version.namespace); return builder.toString(); } diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index 31dc2076a..8f16dcdb3 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -4121,11 +4121,11 @@ public class XmppConnectionService extends Service { } public void fetchMamPreferences(Account account, final OnMamPreferencesFetched callback) { - final boolean legacy = account.getXmppConnection().getFeatures().mamLegacy(); + final MessageArchiveService.Version version = MessageArchiveService.Version.get(account); IqPacket request = new IqPacket(IqPacket.TYPE.GET); - request.addChild("prefs",legacy ? Namespace.MAM_LEGACY : Namespace.MAM); + request.addChild("prefs", version.namespace); sendIqPacket(account, request, (account1, packet) -> { - Element prefs = packet.findChild("prefs",legacy ? Namespace.MAM_LEGACY : Namespace.MAM); + Element prefs = packet.findChild("prefs", version.namespace); if (packet.getType() == IqPacket.TYPE.RESULT && prefs != null) { callback.onPreferencesFetched(prefs); } else { diff --git a/src/main/java/de/pixart/messenger/utils/Namespace.java b/src/main/java/de/pixart/messenger/utils/Namespace.java index c3ff29697..d76e4fede 100644 --- a/src/main/java/de/pixart/messenger/utils/Namespace.java +++ b/src/main/java/de/pixart/messenger/utils/Namespace.java @@ -8,8 +8,6 @@ public final class Namespace { public static final String HTTP_UPLOAD = "urn:xmpp:http:upload:0"; public static final String HTTP_UPLOAD_LEGACY = "urn:xmpp:http:upload"; public static final String STANZA_IDS = "urn:xmpp:sid:0"; - public static final String MAM = "urn:xmpp:mam:2"; - public static final String MAM_LEGACY = "urn:xmpp:mam:0"; public static final String IDLE = "urn:xmpp:idle:1"; public static final String DATA = "jabber:x:data"; public static final String OOB = "jabber:x:oob"; diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java index d8fdb540a..2a223b259 100644 --- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java +++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java @@ -31,6 +31,7 @@ import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; @@ -71,6 +72,7 @@ import de.pixart.messenger.entities.ServiceDiscoveryResult; import de.pixart.messenger.generator.IqGenerator; import de.pixart.messenger.persistance.FileBackend; import de.pixart.messenger.services.MemorizingTrustManager; +import de.pixart.messenger.services.MessageArchiveService; import de.pixart.messenger.services.NotificationService; import de.pixart.messenger.services.XmppConnectionService; import de.pixart.messenger.ui.EditAccountActivity; @@ -1821,13 +1823,12 @@ public class XmppConnection implements Runnable { } public boolean mam() { - return hasDiscoFeature(account.getJid().asBareJid(), Namespace.MAM) - || hasDiscoFeature(account.getJid().asBareJid(), Namespace.MAM_LEGACY); + return MessageArchiveService.Version.has(getAccountFeatures()); } - public boolean mamLegacy() { - return !hasDiscoFeature(account.getJid().asBareJid(), Namespace.MAM) - && hasDiscoFeature(account.getJid().asBareJid(), Namespace.MAM_LEGACY); + public List getAccountFeatures() { + ServiceDiscoveryResult result = connection.disco.get(account.getJid().asBareJid()); + return result == null ? Collections.emptyList() : result.getFeatures(); } public boolean push() { -- cgit v1.2.3