avoid race conditions when downloading files or decrypting pgp messages and waiting for sm catchup

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/parser/MessageParser.java         |  5 
src/main/java/eu/siacs/conversations/services/NotificationService.java | 13 
src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java          | 16 
3 files changed, 23 insertions(+), 11 deletions(-)

Detailed changes

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

@@ -624,9 +624,6 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 			} else if (notify) {
 				if (query != null && query.isCatchup()) {
 					mXmppConnectionService.getNotificationService().pushFromBacklog(message);
-				} else if (account.getXmppConnection().isWaitingForSmCatchup()) {
-					account.getXmppConnection().incrementSmCatchupMessageCounter();
-					mXmppConnectionService.getNotificationService().pushFromBacklog(message);
 				} else {
 					mXmppConnectionService.getNotificationService().push(message);
 				}
@@ -700,7 +697,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 		if (displayed != null) {
 			if (packet.fromAccount(account)) {
 				Conversation conversation = mXmppConnectionService.find(account,counterpart.toBareJid());
-				if (conversation != null) {
+				if (conversation != null && (query == null || query.isCatchup())) {
 					mXmppConnectionService.markRead(conversation);
 				}
 			} else {

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

@@ -46,6 +46,7 @@ import eu.siacs.conversations.ui.SettingsActivity;
 import eu.siacs.conversations.ui.TimePreference;
 import eu.siacs.conversations.utils.GeoHelper;
 import eu.siacs.conversations.utils.UIHelper;
+import eu.siacs.conversations.xmpp.XmppConnection;
 
 public class NotificationService {
 
@@ -170,6 +171,18 @@ public class NotificationService {
 	}
 
 	public void push(final Message message) {
+		synchronized (message.getConversation().getAccount()) {
+			final XmppConnection connection = message.getConversation().getAccount().getXmppConnection();
+			if (connection.isWaitingForSmCatchup()) {
+				connection.incrementSmCatchupMessageCounter();
+				pushFromBacklog(message);
+			} else {
+				pushNow(message);
+			}
+		}
+	}
+
+	private void pushNow(final Message message) {
 		mXmppConnectionService.updateUnreadCountBadge();
 		if (!notify(message)) {
 			Log.d(Config.LOGTAG,message.getConversation().getAccount().getJid().toBareJid()+": suppressing notification because turned off");

src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java 🔗

@@ -96,7 +96,7 @@ public class XmppConnection implements Runnable {
 	private static final int PACKET_IQ = 0;
 	private static final int PACKET_MESSAGE = 1;
 	private static final int PACKET_PRESENCE = 2;
-	protected Account account;
+	protected final Account account;
 	private final WakeLock wakeLock;
 	private Socket socket;
 	private XmlReader tagReader;
@@ -133,7 +133,7 @@ public class XmppConnection implements Runnable {
 	private OnBindListener bindListener = null;
 	private final ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
 	private OnMessageAcknowledged acknowledgedListener = null;
-	private XmppConnectionService mXmppConnectionService = null;
+	private final XmppConnectionService mXmppConnectionService;
 
 	private SaslMechanism saslMechanism;
 
@@ -626,11 +626,13 @@ public class XmppConnection implements Runnable {
 				final AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
 				tagWriter.writeStanzaAsync(ack);
 			} else if (nextTag.isStart("a")) {
-				if (mWaitingForSmCatchup.compareAndSet(true,false)) {
-					int count = mSmCatchupMessageCounter.get();
-					Log.d(Config.LOGTAG,account.getJid().toBareJid()+": SM catchup complete ("+count+")");
-					if (count > 0) {
-						mXmppConnectionService.getNotificationService().finishBacklog(true,account);
+				synchronized (account) {
+					if (mWaitingForSmCatchup.compareAndSet(true, false)) {
+						int count = mSmCatchupMessageCounter.get();
+						Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": SM catchup complete (" + count + ")");
+						if (count > 0) {
+							mXmppConnectionService.getNotificationService().finishBacklog(true, account);
+						}
 					}
 				}
 				final Element ack = tagReader.readElement(nextTag);