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