Allow disco of bare jid when offline

Stephen Paul Weber created

Change summary

src/main/java/eu/siacs/conversations/entities/Presence.java              |  2 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 19 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java        |  8 
3 files changed, 20 insertions(+), 9 deletions(-)

Detailed changes

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

@@ -48,7 +48,7 @@ public class Presence implements Comparable<Presence> {
 	private final String node;
 	private final String message;
 
-	private Presence(Status status, String ver, String hash, String node, String message) {
+	public Presence(Status status, String ver, String hash, String node, String message) {
 		this.status = status;
 		this.ver = ver;
 		this.hash = hash;

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

@@ -4956,8 +4956,8 @@ public class XmppConnectionService extends Service {
     }
 
     public void fetchCaps(Account account, final Jid jid, final Presence presence, Runnable cb) {
-        final Pair<String, String> key = new Pair<>(presence.getHash(), presence.getVer());
-        final ServiceDiscoveryResult disco = getCachedServiceDiscoveryResult(key);
+        final Pair<String, String> key = presence == null ? null : new Pair<>(presence.getHash(), presence.getVer());
+        final ServiceDiscoveryResult disco = key == null ? null : getCachedServiceDiscoveryResult(key);
 
         if (disco != null) {
             presence.setServiceDiscoveryResult(disco);
@@ -4973,19 +4973,19 @@ public class XmppConnectionService extends Service {
         } else {
             final IqPacket request = new IqPacket(IqPacket.TYPE.GET);
             request.setTo(jid);
-            final String node = presence.getNode();
-            final String ver = presence.getVer();
+            final String node = presence == null ? null : presence.getNode();
+            final String ver = presence == null ? null : presence.getVer();
             final Element query = request.query(Namespace.DISCO_INFO);
             if (node != null && ver != null) {
                 query.setAttribute("node", node + "#" + ver);
             }
-            Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": making disco request for " + key.second + " to " + jid);
+            Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": making disco request for " + (key == null ? "" : key.second) + " to " + jid);
             sendIqPacket(account, request, (a, response) -> {
                 if (response.getType() == IqPacket.TYPE.RESULT) {
                     final ServiceDiscoveryResult discoveryResult = new ServiceDiscoveryResult(response);
-                    if (presence.getVer() == null || presence.getVer().equals(discoveryResult.getVer())) {
+                    if (presence == null || presence.getVer() == null || presence.getVer().equals(discoveryResult.getVer())) {
                         databaseBackend.insertDiscoveryResult(discoveryResult);
-                        injectServiceDiscoveryResult(a.getRoster(), presence.getHash(), presence.getVer(), jid.getResource(), discoveryResult);
+                        injectServiceDiscoveryResult(a.getRoster(), presence == null ? null : presence.getHash(), presence == null ? null : presence.getVer(), jid.getResource(), discoveryResult);
                         if (discoveryResult.hasIdentity("gateway", "pstn")) {
                             final Contact contact = account.getRoster().getContact(jid);
                             contact.registerAsPhoneAccount(this);
@@ -5016,6 +5016,11 @@ public class XmppConnectionService extends Service {
             if (onePresence != null) {
                 onePresence.setServiceDiscoveryResult(disco);
                 serviceDiscoverySet = true;
+            } else if (resource == null && hash == null && ver == null) {
+                Presence p = new Presence(Presence.Status.OFFLINE, null, null, null, "");
+                p.setServiceDiscoveryResult(disco);
+                contact.updatePresence("", p);
+                serviceDiscoverySet = true;
             }
             if (hash != null && ver != null) {
                 for (final Presence presence : contact.getPresences().getPresences()) {

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -83,6 +83,7 @@ import io.ipfs.cid.Cid;
 
 import java.io.File;
 import java.net.URISyntaxException;
+import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -1819,7 +1820,12 @@ public class ConversationFragment extends XmppFragment
     }
 
     private void refreshFeatureDiscovery() {
-        for (Map.Entry<String, Presence> entry : conversation.getContact().getPresences().getPresencesMap().entrySet()) {
+        Set<Map.Entry<String, Presence>> presences = conversation.getContact().getPresences().getPresencesMap().entrySet();
+        if (presences.isEmpty()) {
+            presences = new HashSet<>();
+            presences.add(new AbstractMap.SimpleEntry("", null));
+        }
+        for (Map.Entry<String, Presence> entry : presences) {
             Jid jid = conversation.getContact().getJid();
             if (!entry.getKey().equals("")) jid = jid.withResource(entry.getKey());
             activity.xmppConnectionService.fetchCaps(conversation.getAccount(), jid, entry.getValue(), () -> {