MAM: look at total count for completness. parse fin correctly

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/Conversation.java          |  4 
src/main/java/eu/siacs/conversations/parser/MessageParser.java           |  2 
src/main/java/eu/siacs/conversations/services/MessageArchiveService.java | 30 
3 files changed, 24 insertions(+), 12 deletions(-)

Detailed changes

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

@@ -955,9 +955,9 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
 		}
 	}
 
-	public void prepend(Message message) {
+	public void prepend(int offset, Message message) {
 		synchronized (this.messages) {
-			this.messages.add(0,message);
+			this.messages.add(Math.min(offset,this.messages.size()),message);
 		}
 	}
 

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

@@ -631,7 +631,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 			}
 
 			if (query != null && query.getPagingOrder() == MessageArchiveService.PagingOrder.REVERSE) {
-				conversation.prepend(message);
+				conversation.prepend(query.getActualInThisQuery(),message);
 			} else {
 				conversation.add(message);
 			}

src/main/java/eu/siacs/conversations/services/MessageArchiveService.java 🔗

@@ -184,7 +184,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 							}
 						}
 					} else if (packet.getType() == IqPacket.TYPE.RESULT && fin != null ) {
-						processFin(fin);
+						processFin(query, fin);
 					} else if (packet.getType() == IqPacket.TYPE.RESULT && query.isLegacy()) {
 						//do nothing
 					} else {
@@ -254,18 +254,15 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 	public void processFinLegacy(Element fin, Jid from) {
 		Query query = findQuery(fin.getAttribute("queryid"));
 		if (query != null && query.validFrom(from)) {
-			processFin(fin);
+			processFin(query, fin);
 		}
 	}
 
-	public void processFin(Element fin) {
-		Query query = findQuery(fin.getAttribute("queryid"));
-		if (query == null) {
-			return;
-		}
+	private void processFin(Query query, Element fin) {
 		boolean complete = fin.getAttributeAsBoolean("complete");
 		Element set = fin.findChild("set","http://jabber.org/protocol/rsm");
 		Element last = set == null ? null : set.findChild("last");
+		String count = set == null ? null : set.findChildContent("count");
 		Element first = set == null ? null : set.findChild("first");
 		Element relevant = query.getPagingOrder() == PagingOrder.NORMAL ? last : first;
 		boolean abort = (!query.isCatchup() && query.getTotalCount() >= Config.PAGE_SIZE) || query.getTotalCount() >= Config.MAM_MAX_MESSAGES;
@@ -273,9 +270,18 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 			query.getConversation().setFirstMamReference(first == null ? null : first.getContent());
 		}
 		if (complete || relevant == null || abort) {
-			final boolean done = (complete || query.getActualMessageCount() == 0) && !query.isCatchup();
+			boolean done = !query.isCatchup();
+			if (count != null && !query.isCatchup()) {
+				try {
+					done = Integer.parseInt(count) <= query.getTotalCount();
+				} catch (NumberFormatException e) {
+					done = false;
+				}
+			}
+			done = done || (query.getActualMessageCount() == 0 && !query.isCatchup());
 			this.finalizeQuery(query, done);
-			Log.d(Config.LOGTAG,query.getAccount().getJid().toBareJid()+": finished mam after "+query.getTotalCount()+"("+query.getActualMessageCount()+") messages. messages left="+Boolean.toString(!done));
+
+			Log.d(Config.LOGTAG,query.getAccount().getJid().toBareJid()+": finished mam after "+query.getTotalCount()+"("+query.getActualMessageCount()+") messages. messages left="+Boolean.toString(!done)+" count="+count);
 			if (query.isCatchup() && query.getActualMessageCount() > 0) {
 				mXmppConnectionService.getNotificationService().finishBacklog(true,query.getAccount());
 			}
@@ -330,6 +336,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 	public class Query {
 		private int totalCount = 0;
 		private int actualCount = 0;
+		private int actualInThisQuery = 0;
 		private long start;
 		private long end;
 		private String queryId;
@@ -453,6 +460,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 		}
 
 		public void incrementActualMessageCount() {
+			this.actualInThisQuery++;
 			this.actualCount++;
 		}
 
@@ -464,6 +472,10 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 			return this.actualCount;
 		}
 
+		public int getActualInThisQuery() {
+			return this.actualInThisQuery;
+		}
+
 		public boolean validFrom(Jid from) {
 			if (muc()) {
 				return getWith().equals(from);