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

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java   | 16 
src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java     |  7 
src/main/java/eu/siacs/conversations/xmpp/jingle/RtpCapability.java | 14 
3 files changed, 31 insertions(+), 6 deletions(-)

Detailed changes

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

@@ -156,7 +156,6 @@ import eu.siacs.conversations.utils.GeoHelper;
 import eu.siacs.conversations.utils.MessageUtils;
 import eu.siacs.conversations.utils.MimeUtils;
 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;
@@ -175,6 +174,19 @@ import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession;
 import eu.siacs.conversations.xmpp.jingle.RtpCapability;
 import eu.siacs.conversations.xmpp.stanzas.IqPacket;
 
+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,
@@ -2063,7 +2075,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 🔗

@@ -72,6 +72,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
@@ -1525,10 +1526,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;
@@ -84,6 +86,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;