Parse all SIMS and OOBs on a message

Stephen Paul Weber created

Use a set that keys on URL so that we don't get duplicates.

Still only store the first one for now.

Change summary

src/main/java/eu/siacs/conversations/entities/Message.java     | 10 +
src/main/java/eu/siacs/conversations/parser/MessageParser.java | 27 ++-
2 files changed, 27 insertions(+), 10 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Message.java 🔗

@@ -1125,6 +1125,16 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
             if (runtime > 0) builder.append('|').append(runtime);
             return builder.toString();
         }
+
+        public boolean equals(Object o) {
+            if (!(o instanceof FileParams)) return false;
+
+            return url.equals(((FileParams) o).url);
+        }
+
+        public int hashCode() {
+            return url.hashCode();
+        }
     }
 
     public void setFingerprint(String fingerprint) {

src/main/java/eu/siacs/conversations/parser/MessageParser.java 🔗

@@ -11,6 +11,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -410,13 +411,19 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
         final Element mucUserElement = packet.findChild("x", Namespace.MUC_USER);
         final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted");
         final Element replaceElement = packet.findChild("replace", "urn:xmpp:message-correct:0");
-        Element oob = packet.findChild("x", Namespace.OOB);
-        if (oob != null && oob.findChildContent("url") == null) {
-            oob = null;
+        Set<Message.FileParams> attachments = new LinkedHashSet<>();
+        for (Element child : packet.getChildren()) {
+            // SIMS first so they get preference in the set
+            if (child.getName().equals("reference") && child.getNamespace().equals("urn:xmpp:reference:0")) {
+                if (child.findChild("media-sharing", "urn:xmpp:sims:1") != null) {
+                    attachments.add(new Message.FileParams(child));
+                }
+            }
         }
-        final Element reference = packet.findChild("reference", "urn:xmpp:reference:0");
-        if (reference != null && reference.findChild("media-sharing", "urn:xmpp:sims:1") != null) {
-            oob = reference;
+        for (Element child : packet.getChildren()) {
+            if (child.getName().equals("x") && child.getNamespace().equals(Namespace.OOB)) {
+                attachments.add(new Message.FileParams(child));
+            }
         }
         String replacementId = replaceElement == null ? null : replaceElement.getAttribute("id");
         if (replacementId == null) {
@@ -485,7 +492,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
             }
         }
 
-        if ((body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || oob != null || html != null) && !isMucStatusMessage) {
+        if ((body != null || pgpEncrypted != null || (axolotlEncrypted != null && axolotlEncrypted.hasChild("payload")) || !attachments.isEmpty() || html != null) && !isMucStatusMessage) {
             final boolean conversationIsProbablyMuc = isTypeGroupChat || mucUserElement != null || account.getXmppConnection().getMucServersWithholdAccount().contains(counterpart.getDomain().toEscapedString());
             final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.asBareJid(), conversationIsProbablyMuc, false, query, false);
             final boolean conversationMultiMode = conversation.getMode() == Conversation.MODE_MULTI;
@@ -583,7 +590,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
                 if (conversationMultiMode) {
                     message.setTrueCounterpart(origin);
                 }
-            } else if (body == null && oob != null) {
+            } else if (body == null && !attachments.isEmpty()) {
                 message = new Message(conversation, "", Message.ENCRYPTION_NONE, status);
             } else {
                 message = new Message(conversation, body == null ? "HTML-only message" : body.content, Message.ENCRYPTION_NONE, status);
@@ -599,8 +606,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
             message.setServerMsgId(serverMsgId);
             message.setCarbon(isCarbon);
             message.setTime(timestamp);
-            if (oob != null) {
-                message.setFileParams(new Message.FileParams(oob));
+            if (!attachments.isEmpty()) {
+                message.setFileParams(attachments.iterator().next());
                 if (CryptoHelper.isPgpEncryptedUrl(message.getFileParams().url)) {
                     message.setEncryption(Message.ENCRYPTION_DECRYPTED);
                 }