clean caps cache when resources go unavailable

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/parser/PresenceParser.java          |  1 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  4 
src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java            |  3 
src/main/java/eu/siacs/conversations/xmpp/manager/DiscoManager.java      | 16 
4 files changed, 24 insertions(+)

Detailed changes

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

@@ -419,6 +419,7 @@ public class PresenceParser extends AbstractParser
             if (contact.setLastseen(AbstractParser.parseTimestamp(packet, 0L, true))) {
                 contact.flagInactive();
             }
+            getManager(DiscoManager.class).clear(from);
             if (from.isBareJid()) {
                 contact.clearPresences();
             } else {

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

@@ -4209,6 +4209,10 @@ public class XmppConnectionService extends Service {
                     conversation.getAccount().getJid().asBareJid()
                             + ": leaving muc "
                             + conversation.getJid());
+            final var connection = account.getXmppConnection();
+            if (connection != null) {
+                connection.getManager(DiscoManager.class).clear(conversation.getJid().asBareJid());
+            }
         } else {
             synchronized (account.pendingConferenceLeaves) {
                 account.pendingConferenceLeaves.add(conversation);

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

@@ -216,6 +216,9 @@ public class XmppConnection implements Runnable {
         this.mXmppConnectionService = service;
         this.appSettings = mXmppConnectionService.getAppSettings();
         this.presenceListener = new PresenceParser(service, this);
+        // TODO rename this to Iq request handler (it handles only IQ get and set; throw assert
+        // error in handler just to be safe)
+        // TODO requires roster and blocking not to be handled by this
         this.unregisteredIqListener = new IqParser(service, this);
         this.messageListener = new MessageParser(service, this);
         this.bindListener = new BindProcessor(service, this);

src/main/java/eu/siacs/conversations/xmpp/manager/DiscoManager.java 🔗

@@ -440,6 +440,22 @@ public class DiscoManager extends AbstractManager {
         }
     }
 
+    public void clear(final Jid address) {
+        synchronized (this.entityInformation) {
+            if (address.isFullJid()) {
+                this.entityInformation.remove(address);
+            } else {
+                final var iterator = this.entityInformation.entrySet().iterator();
+                while (iterator.hasNext()) {
+                    final var entry = iterator.next();
+                    if (entry.getKey().asBareJid().equals(address)) {
+                        iterator.remove();
+                    }
+                }
+            }
+        }
+    }
+
     public static final class CapsHashMismatchException extends IllegalStateException {
         public CapsHashMismatchException(final String message) {
             super(message);