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