RtpCapability.java

  1package eu.siacs.conversations.xmpp.jingle;
  2
  3import com.google.common.base.Strings;
  4import com.google.common.collect.Collections2;
  5import com.google.common.collect.ImmutableSet;
  6
  7import java.util.ArrayList;
  8import java.util.Arrays;
  9import java.util.Collection;
 10import java.util.Collections;
 11import java.util.List;
 12import java.util.Map;
 13import java.util.Set;
 14
 15import eu.siacs.conversations.entities.Contact;
 16import eu.siacs.conversations.entities.Presence;
 17import eu.siacs.conversations.entities.Presences;
 18import eu.siacs.conversations.entities.ServiceDiscoveryResult;
 19import eu.siacs.conversations.xml.Namespace;
 20
 21public class RtpCapability {
 22
 23    private static final List<String> BASIC_RTP_REQUIREMENTS = Arrays.asList(
 24            Namespace.JINGLE,
 25            Namespace.JINGLE_TRANSPORT_ICE_UDP,
 26            Namespace.JINGLE_APPS_RTP,
 27            Namespace.JINGLE_APPS_DTLS
 28    );
 29    private static final Collection<String> VIDEO_REQUIREMENTS = Arrays.asList(
 30            Namespace.JINGLE_FEATURE_AUDIO,
 31            Namespace.JINGLE_FEATURE_VIDEO
 32    );
 33
 34    public static Capability check(final Presence presence) {
 35        final ServiceDiscoveryResult disco = presence.getServiceDiscoveryResult();
 36        final Set<String> features = disco == null ? Collections.emptySet() : ImmutableSet.copyOf(disco.getFeatures());
 37        if (features.containsAll(BASIC_RTP_REQUIREMENTS)) {
 38            if (features.containsAll(VIDEO_REQUIREMENTS)) {
 39                return Capability.VIDEO;
 40            }
 41            if (features.contains(Namespace.JINGLE_FEATURE_AUDIO)) {
 42                return Capability.AUDIO;
 43            }
 44        }
 45        return Capability.NONE;
 46    }
 47
 48    public static String[] filterPresences(final Contact contact, Capability required) {
 49        final Presences presences = contact.getPresences();
 50        final ArrayList<String> resources = new ArrayList<>();
 51        for (final Map.Entry<String, Presence> presence : presences.getPresencesMap().entrySet()) {
 52            final Capability capability = check(presence.getValue());
 53            if (capability == Capability.NONE) {
 54                continue;
 55            }
 56            if (required == Capability.AUDIO || capability == required) {
 57                resources.add(presence.getKey());
 58            }
 59        }
 60        return resources.toArray(new String[0]);
 61    }
 62
 63    public static Capability check(final Contact contact) {
 64        return check(contact, true);
 65    }
 66
 67    public static Capability check(final Contact contact, final boolean allowFallback) {
 68        final Presences presences = contact.getPresences();
 69        if (presences.isEmpty() && allowFallback && contact.getAccount().isEnabled()) {
 70            return contact.getRtpCapability();
 71        }
 72        Capability result = Capability.NONE;
 73        for (final Presence presence : presences.getPresences()) {
 74            Capability capability = check(presence);
 75            if (capability == Capability.VIDEO) {
 76                result = capability;
 77            } else if (capability == Capability.AUDIO && result == Capability.NONE) {
 78                result = capability;
 79            }
 80        }
 81        return result;
 82    }
 83
 84    // do all devices that support Rtp Call also support JMI?
 85    public static boolean jmiSupport(final Contact contact) {
 86        return !Collections2.transform(
 87                Collections2.filter(
 88                        contact.getPresences().getPresences(),
 89                        p -> RtpCapability.check(p) != RtpCapability.Capability.NONE),
 90                p -> {
 91                    ServiceDiscoveryResult disco = p.getServiceDiscoveryResult();
 92                    return disco != null && disco.getFeatures().contains(Namespace.JINGLE_MESSAGE);
 93                }).contains(false);
 94    }
 95
 96    public enum Capability {
 97        NONE, AUDIO, VIDEO;
 98
 99        public static Capability of(String value) {
100            if (Strings.isNullOrEmpty(value)) {
101                return NONE;
102            }
103            try {
104                return valueOf(value);
105            } catch (IllegalArgumentException e) {
106                return NONE;
107            }
108        }
109    }
110
111}