MAM: update previously sent messages with server msg id during mam query

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/Conversation.java | 10 
src/main/java/eu/siacs/conversations/parser/MessageParser.java  | 28 ++
2 files changed, 32 insertions(+), 6 deletions(-)

Detailed changes

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

@@ -804,15 +804,19 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
 		return this.bookmark;
 	}
 
-	public boolean hasDuplicateMessage(Message message) {
+	public Message findDuplicateMessage(Message message) {
 		synchronized (this.messages) {
 			for (int i = this.messages.size() - 1; i >= 0; --i) {
 				if (this.messages.get(i).similar(message)) {
-					return true;
+					return this.messages.get(i);
 				}
 			}
 		}
-		return false;
+		return null;
+	}
+
+	public boolean hasDuplicateMessage(Message message) {
+		return findDuplicateMessage(message) != null;
 	}
 
 	public Message findSentMessageWithBody(String body) {

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

@@ -474,6 +474,14 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 					if (query == null &&  extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), isTypeGroupChat, packet)) {
 						mXmppConnectionService.updateConversationUi();
 					}
+					if (query != null && status == Message.STATUS_SEND && remoteMsgId != null) {
+						Message previouslySent = conversation.findSentMessageWithUuid(remoteMsgId);
+						if (previouslySent != null && previouslySent.getServerMsgId() == null && serverMsgId != null) {
+							previouslySent.setServerMsgId(serverMsgId);
+							mXmppConnectionService.databaseBackend.updateMessage(previouslySent);
+							Log.d(Config.LOGTAG,account.getJid().toBareJid()+": encountered previously sent OMEMO message without serverId. updating...");
+						}
+					}
 					return;
 				}
 				if (conversationMultiMode) {
@@ -577,9 +585,23 @@ 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 && conversation.hasDuplicateMessage(message)) {
-				Log.d(Config.LOGTAG, "skipping duplicate message from " + message.getCounterpart().toString() + " " + message.getBody());
-				return;
+			if (checkForDuplicates ) {
+				final Message duplicate = conversation.findDuplicateMessage(message);
+				if (duplicate != null) {
+					final boolean serverMsgIdUpdated;
+					if (duplicate.getStatus() != Message.STATUS_RECEIVED
+							&& duplicate.getUuid().equals(message.getRemoteMsgId())
+							&& duplicate.getServerMsgId() == null
+							&& message.getServerMsgId() != null) {
+						duplicate.setServerMsgId(message.getServerMsgId());
+						mXmppConnectionService.databaseBackend.updateMessage(message);
+						serverMsgIdUpdated = true;
+					} else {
+						serverMsgIdUpdated = false;
+					}
+					Log.d(Config.LOGTAG, "skipping duplicate message with " + message.getCounterpart()+". serverMsgIdUpdated="+Boolean.toString(serverMsgIdUpdated));
+					return;
+				}
 			}
 
 			if (query != null && query.getPagingOrder() == MessageArchiveService.PagingOrder.REVERSE) {