do not use JMI if any rtp capable device does not support it

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/Presences.java        | 14 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java   | 30 
src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java     |  7 
src/main/java/eu/siacs/conversations/xmpp/jingle/RtpCapability.java | 14 
4 files changed, 31 insertions(+), 34 deletions(-)

Detailed changes

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

@@ -134,20 +134,6 @@ public class Presences {
         return true;
     }
 
-    public boolean anySupport(final String namespace) {
-        synchronized (this.presences) {
-            if (this.presences.size() == 0) {
-                return true;
-            }
-            for (Presence presence : this.presences.values()) {
-                ServiceDiscoveryResult disco = presence.getServiceDiscoveryResult();
-                if (disco != null && disco.getFeatures().contains(namespace)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
 
     public Pair<Map<String, String>, Map<String, String>> toTypeAndNameMap() {
         Map<String, String> typeMap = new HashMap<>();

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

@@ -64,19 +64,6 @@ import androidx.databinding.DataBindingUtil;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.crypto.axolotl.AxolotlService;
@@ -123,13 +110,11 @@ import eu.siacs.conversations.utils.Compatibility;
 import eu.siacs.conversations.utils.GeoHelper;
 import eu.siacs.conversations.utils.MessageUtils;
 import eu.siacs.conversations.utils.NickValidityChecker;
-import eu.siacs.conversations.utils.Patterns;
 import eu.siacs.conversations.utils.PermissionUtils;
 import eu.siacs.conversations.utils.QuickLoader;
 import eu.siacs.conversations.utils.StylingHelper;
 import eu.siacs.conversations.utils.TimeFrameUtils;
 import eu.siacs.conversations.utils.UIHelper;
-import eu.siacs.conversations.xml.Namespace;
 import eu.siacs.conversations.xmpp.Jid;
 import eu.siacs.conversations.xmpp.XmppConnection;
 import eu.siacs.conversations.xmpp.chatstate.ChatState;
@@ -140,6 +125,19 @@ import eu.siacs.conversations.xmpp.jingle.Media;
 import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession;
 import eu.siacs.conversations.xmpp.jingle.RtpCapability;
 
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 public class ConversationFragment extends XmppFragment
         implements EditMessage.KeyboardListener,
                 MessageAdapter.OnContactPictureLongClicked,
@@ -1611,7 +1609,7 @@ public class ConversationFragment extends XmppFragment
             return;
         }
         final Contact contact = conversation.getContact();
-        if (contact.getPresences().anySupport(Namespace.JINGLE_MESSAGE)) {
+        if (RtpCapability.jmiSupport(contact)) {
             triggerRtpSession(contact.getAccount(), contact.getJid().asBareJid(), action);
         } else {
             final RtpCapability.Capability capability;

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

@@ -70,6 +70,7 @@ import eu.siacs.conversations.xmpp.jingle.ContentAddition;
 import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
 import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
 import eu.siacs.conversations.xmpp.jingle.Media;
+import eu.siacs.conversations.xmpp.jingle.RtpCapability;
 import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
 
 public class RtpSessionActivity extends XmppActivity
@@ -1484,10 +1485,8 @@ public class RtpSessionActivity extends XmppActivity
             final Account account, Jid with, final RtpEndUserState state, final Set<Media> media) {
         final Intent intent = new Intent(Intent.ACTION_VIEW);
         intent.putExtra(EXTRA_ACCOUNT, account.getJid().toEscapedString());
-        if (account.getRoster()
-                .getContact(with)
-                .getPresences()
-                .anySupport(Namespace.JINGLE_MESSAGE)) {
+        if (RtpCapability.jmiSupport(account.getRoster()
+                .getContact(with))) {
             intent.putExtra(EXTRA_WITH, with.asBareJid().toEscapedString());
         } else {
             intent.putExtra(EXTRA_WITH, with.toEscapedString());

src/main/java/eu/siacs/conversations/xmpp/jingle/RtpCapability.java 🔗

@@ -1,9 +1,11 @@
 package eu.siacs.conversations.xmpp.jingle;
 
 import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -77,6 +79,18 @@ public class RtpCapability {
         return result;
     }
 
+    // do all devices that support Rtp Call also support JMI?
+    public static boolean jmiSupport(final Contact contact) {
+        return !Collections2.transform(
+                Collections2.filter(
+                        contact.getPresences().getPresences(),
+                        p -> RtpCapability.check(p) != RtpCapability.Capability.NONE),
+                p -> {
+                    ServiceDiscoveryResult disco = p.getServiceDiscoveryResult();
+                    return disco != null && disco.getFeatures().contains(Namespace.JINGLE_MESSAGE);
+                }).contains(false);
+    }
+
     public enum Capability {
         NONE, AUDIO, VIDEO;