Cache known gateways

Stephen Paul Weber created

Change summary

src/main/java/eu/siacs/conversations/entities/Account.java               | 21 
src/main/java/eu/siacs/conversations/entities/Contact.java               |  6 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  2 
3 files changed, 29 insertions(+)

Detailed changes

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

@@ -10,6 +10,7 @@ import androidx.core.graphics.ColorUtils;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.HashMultimap;
 
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -112,6 +113,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
     private String fastMechanism;
     private String fastToken;
     private Integer color = null;
+    private final HashMultimap<String, Contact> gateways = HashMultimap.create();
 
     public Account(final Jid jid, final String password) {
         this(
@@ -649,6 +651,25 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
         return this.roster;
     }
 
+    public void refreshCapsFor(Contact contact) {
+        for (final var k : gateways.keySet()) {
+            gateways.remove(k, contact);
+        }
+        for (final var p : contact.getPresences().getPresences()) {
+            final var disco = p.getServiceDiscoveryResult();
+            if (disco == null) continue;
+            for (final var identity : disco.getIdentities()) {
+                if ("gateway".equals(identity.getCategory())) {
+                    gateways.put(identity.getType(), contact);
+                }
+            }
+        }
+    }
+
+    public Set<Contact> getGateways(final String type) {
+        return gateways.get(type);
+    }
+
     public Collection<Bookmark> getBookmarks() {
         synchronized (this.bookmarks) {
             return ImmutableList.copyOf(this.bookmarks.values());

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

@@ -298,11 +298,13 @@ public class Contact implements ListItem, Blockable {
 
     public void removePresence(final String resource) {
         this.presences.removePresence(resource);
+        refreshCaps();
     }
 
     public void clearPresences() {
         this.presences.clearPresences();
         this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST);
+        refreshCaps();
     }
 
     public Presence.Status getShownStatus() {
@@ -737,6 +739,10 @@ public class Contact implements ListItem, Blockable {
         return !Objects.equals(previous, this.rtpCapability);
     }
 
+    public void refreshCaps() {
+        account.refreshCapsFor(this);
+    }
+
     public RtpCapability.Capability getRtpCapability() {
         return this.rtpCapability == null ? RtpCapability.Capability.NONE : this.rtpCapability;
     }

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

@@ -5629,6 +5629,7 @@ public class XmppConnectionService extends Service {
             if (contact.refreshRtpCapability()) {
                 syncRoster(account);
             }
+            contact.refreshCaps();
             if (disco.hasIdentity("gateway", "pstn")) {
                 contact.registerAsPhoneAccount(this);
                 mQuickConversationsService.considerSyncBackground(false);
@@ -5696,6 +5697,7 @@ public class XmppConnectionService extends Service {
             }
             if (serviceDiscoverySet) {
                 rosterNeedsSync |= contact.refreshRtpCapability();
+                contact.refreshCaps();
             }
         }
         if (rosterNeedsSync) {