remember last rtp capability
This commit is contained in:
parent
e087b594ff
commit
e711b3d294
|
@ -18,6 +18,7 @@ import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
@ -27,6 +28,7 @@ import eu.siacs.conversations.services.QuickConversationsService;
|
||||||
import eu.siacs.conversations.utils.JidHelper;
|
import eu.siacs.conversations.utils.JidHelper;
|
||||||
import eu.siacs.conversations.utils.UIHelper;
|
import eu.siacs.conversations.utils.UIHelper;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
|
import eu.siacs.conversations.xmpp.jingle.RtpCapability;
|
||||||
import eu.siacs.conversations.xmpp.pep.Avatar;
|
import eu.siacs.conversations.xmpp.pep.Avatar;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
|
@ -46,6 +48,7 @@ public class Contact implements ListItem, Blockable {
|
||||||
public static final String LAST_PRESENCE = "last_presence";
|
public static final String LAST_PRESENCE = "last_presence";
|
||||||
public static final String LAST_TIME = "last_time";
|
public static final String LAST_TIME = "last_time";
|
||||||
public static final String GROUPS = "groups";
|
public static final String GROUPS = "groups";
|
||||||
|
public static final String RTP_CAPABILITY = "rtpCapability";
|
||||||
private String accountUuid;
|
private String accountUuid;
|
||||||
private String systemName;
|
private String systemName;
|
||||||
private String serverName;
|
private String serverName;
|
||||||
|
@ -64,11 +67,12 @@ public class Contact implements ListItem, Blockable {
|
||||||
private boolean mActive = false;
|
private boolean mActive = false;
|
||||||
private long mLastseen = 0;
|
private long mLastseen = 0;
|
||||||
private String mLastPresence = null;
|
private String mLastPresence = null;
|
||||||
|
private RtpCapability.Capability rtpCapability;
|
||||||
|
|
||||||
public Contact(final String account, final String systemName, final String serverName, final String presenceName,
|
public Contact(final String account, final String systemName, final String serverName, final String presenceName,
|
||||||
final Jid jid, final int subscription, final String photoUri,
|
final Jid jid, final int subscription, final String photoUri,
|
||||||
final Uri systemAccount, final String keys, final String avatar, final long lastseen,
|
final Uri systemAccount, final String keys, final String avatar, final long lastseen,
|
||||||
final String presence, final String groups) {
|
final String presence, final String groups, final RtpCapability.Capability rtpCapability) {
|
||||||
this.accountUuid = account;
|
this.accountUuid = account;
|
||||||
this.systemName = systemName;
|
this.systemName = systemName;
|
||||||
this.serverName = serverName;
|
this.serverName = serverName;
|
||||||
|
@ -96,6 +100,7 @@ public class Contact implements ListItem, Blockable {
|
||||||
}
|
}
|
||||||
this.mLastseen = lastseen;
|
this.mLastseen = lastseen;
|
||||||
this.mLastPresence = presence;
|
this.mLastPresence = presence;
|
||||||
|
this.rtpCapability = rtpCapability;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Contact(final Jid jid) {
|
public Contact(final Jid jid) {
|
||||||
|
@ -129,7 +134,8 @@ public class Contact implements ListItem, Blockable {
|
||||||
cursor.getString(cursor.getColumnIndex(AVATAR)),
|
cursor.getString(cursor.getColumnIndex(AVATAR)),
|
||||||
cursor.getLong(cursor.getColumnIndex(LAST_TIME)),
|
cursor.getLong(cursor.getColumnIndex(LAST_TIME)),
|
||||||
cursor.getString(cursor.getColumnIndex(LAST_PRESENCE)),
|
cursor.getString(cursor.getColumnIndex(LAST_PRESENCE)),
|
||||||
cursor.getString(cursor.getColumnIndex(GROUPS)));
|
cursor.getString(cursor.getColumnIndex(GROUPS)),
|
||||||
|
RtpCapability.Capability.of(cursor.getString(cursor.getColumnIndex(RTP_CAPABILITY))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
|
@ -234,6 +240,7 @@ public class Contact implements ListItem, Blockable {
|
||||||
values.put(LAST_PRESENCE, mLastPresence);
|
values.put(LAST_PRESENCE, mLastPresence);
|
||||||
values.put(LAST_TIME, mLastseen);
|
values.put(LAST_TIME, mLastseen);
|
||||||
values.put(GROUPS, groups.toString());
|
values.put(GROUPS, groups.toString());
|
||||||
|
values.put(RTP_CAPABILITY, rtpCapability == null ? null : rtpCapability.toString());
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,7 +580,18 @@ public class Contact implements ListItem, Blockable {
|
||||||
return (avatar != null && avatar.getFilename() != null) || presenceName != null;
|
return (avatar != null && avatar.getFilename() != null) || presenceName != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class Options {
|
public boolean refreshRtpCapability() {
|
||||||
|
final RtpCapability.Capability previous = this.rtpCapability;
|
||||||
|
this.rtpCapability = RtpCapability.check(this, false);
|
||||||
|
return !Objects.equals(previous, this.rtpCapability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RtpCapability.Capability getRtpCapability() {
|
||||||
|
|
||||||
|
return this.rtpCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Options {
|
||||||
public static final int TO = 0;
|
public static final int TO = 0;
|
||||||
public static final int FROM = 1;
|
public static final int FROM = 1;
|
||||||
public static final int ASKING = 2;
|
public static final int ASKING = 2;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.util.Locale;
|
||||||
|
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
|
|
||||||
public class Presence implements Comparable {
|
public class Presence implements Comparable<Presence> {
|
||||||
|
|
||||||
public enum Status {
|
public enum Status {
|
||||||
CHAT, ONLINE, AWAY, XA, DND, OFFLINE;
|
CHAT, ONLINE, AWAY, XA, DND, OFFLINE;
|
||||||
|
@ -64,7 +64,7 @@ public class Presence implements Comparable {
|
||||||
return new Presence(Status.fromShowString(show), ver, hash, node, message);
|
return new Presence(Status.fromShowString(show), ver, hash, node, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(@NonNull Object other) {
|
public int compareTo(@NonNull Presence other) {
|
||||||
return this.status.compareTo(((Presence)other).status);
|
return this.status.compareTo(((Presence)other).status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,9 @@ public class Presences {
|
||||||
|
|
||||||
public boolean anySupport(final String namespace) {
|
public boolean anySupport(final String namespace) {
|
||||||
synchronized (this.presences) {
|
synchronized (this.presences) {
|
||||||
|
if (this.presences.size() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
for (Presence presence : this.presences.values()) {
|
for (Presence presence : this.presences.values()) {
|
||||||
ServiceDiscoveryResult disco = presence.getServiceDiscoveryResult();
|
ServiceDiscoveryResult disco = presence.getServiceDiscoveryResult();
|
||||||
if (disco != null && disco.getFeatures().contains(namespace)) {
|
if (disco != null && disco.getFeatures().contains(namespace)) {
|
||||||
|
|
|
@ -63,9 +63,9 @@ import eu.siacs.conversations.xmpp.Jid;
|
||||||
public class DatabaseBackend extends SQLiteOpenHelper {
|
public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "history";
|
private static final String DATABASE_NAME = "history";
|
||||||
private static final int DATABASE_VERSION = 47;
|
private static final int DATABASE_VERSION = 48;
|
||||||
private static DatabaseBackend instance = null;
|
private static DatabaseBackend instance = null;
|
||||||
private static String CREATE_CONTATCS_STATEMENT = "create table "
|
private static final String CREATE_CONTATCS_STATEMENT = "create table "
|
||||||
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
|
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
|
||||||
+ Contact.SERVERNAME + " TEXT, " + Contact.SYSTEMNAME + " TEXT,"
|
+ Contact.SERVERNAME + " TEXT, " + Contact.SYSTEMNAME + " TEXT,"
|
||||||
+ Contact.PRESENCE_NAME + " TEXT,"
|
+ Contact.PRESENCE_NAME + " TEXT,"
|
||||||
|
@ -73,12 +73,13 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
+ Contact.PHOTOURI + " TEXT," + Contact.OPTIONS + " NUMBER,"
|
+ Contact.PHOTOURI + " TEXT," + Contact.OPTIONS + " NUMBER,"
|
||||||
+ Contact.SYSTEMACCOUNT + " NUMBER, " + Contact.AVATAR + " TEXT, "
|
+ Contact.SYSTEMACCOUNT + " NUMBER, " + Contact.AVATAR + " TEXT, "
|
||||||
+ Contact.LAST_PRESENCE + " TEXT, " + Contact.LAST_TIME + " NUMBER, "
|
+ Contact.LAST_PRESENCE + " TEXT, " + Contact.LAST_TIME + " NUMBER, "
|
||||||
|
+ Contact.RTP_CAPABILITY + " TEXT,"
|
||||||
+ Contact.GROUPS + " TEXT, FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES "
|
+ Contact.GROUPS + " TEXT, FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES "
|
||||||
+ Account.TABLENAME + "(" + Account.UUID
|
+ Account.TABLENAME + "(" + Account.UUID
|
||||||
+ ") ON DELETE CASCADE, UNIQUE(" + Contact.ACCOUNT + ", "
|
+ ") ON DELETE CASCADE, UNIQUE(" + Contact.ACCOUNT + ", "
|
||||||
+ Contact.JID + ") ON CONFLICT REPLACE);";
|
+ Contact.JID + ") ON CONFLICT REPLACE);";
|
||||||
|
|
||||||
private static String CREATE_DISCOVERY_RESULTS_STATEMENT = "create table "
|
private static final String CREATE_DISCOVERY_RESULTS_STATEMENT = "create table "
|
||||||
+ ServiceDiscoveryResult.TABLENAME + "("
|
+ ServiceDiscoveryResult.TABLENAME + "("
|
||||||
+ ServiceDiscoveryResult.HASH + " TEXT, "
|
+ ServiceDiscoveryResult.HASH + " TEXT, "
|
||||||
+ ServiceDiscoveryResult.VER + " TEXT, "
|
+ ServiceDiscoveryResult.VER + " TEXT, "
|
||||||
|
@ -86,7 +87,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
+ "UNIQUE(" + ServiceDiscoveryResult.HASH + ", "
|
+ "UNIQUE(" + ServiceDiscoveryResult.HASH + ", "
|
||||||
+ ServiceDiscoveryResult.VER + ") ON CONFLICT REPLACE);";
|
+ ServiceDiscoveryResult.VER + ") ON CONFLICT REPLACE);";
|
||||||
|
|
||||||
private static String CREATE_PRESENCE_TEMPLATES_STATEMENT = "CREATE TABLE "
|
private static final String CREATE_PRESENCE_TEMPLATES_STATEMENT = "CREATE TABLE "
|
||||||
+ PresenceTemplate.TABELNAME + "("
|
+ PresenceTemplate.TABELNAME + "("
|
||||||
+ PresenceTemplate.UUID + " TEXT, "
|
+ PresenceTemplate.UUID + " TEXT, "
|
||||||
+ PresenceTemplate.LAST_USED + " NUMBER,"
|
+ PresenceTemplate.LAST_USED + " NUMBER,"
|
||||||
|
@ -94,7 +95,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
+ PresenceTemplate.STATUS + " TEXT,"
|
+ PresenceTemplate.STATUS + " TEXT,"
|
||||||
+ "UNIQUE(" + PresenceTemplate.MESSAGE + "," + PresenceTemplate.STATUS + ") ON CONFLICT REPLACE);";
|
+ "UNIQUE(" + PresenceTemplate.MESSAGE + "," + PresenceTemplate.STATUS + ") ON CONFLICT REPLACE);";
|
||||||
|
|
||||||
private static String CREATE_PREKEYS_STATEMENT = "CREATE TABLE "
|
private static final String CREATE_PREKEYS_STATEMENT = "CREATE TABLE "
|
||||||
+ SQLiteAxolotlStore.PREKEY_TABLENAME + "("
|
+ SQLiteAxolotlStore.PREKEY_TABLENAME + "("
|
||||||
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
||||||
+ SQLiteAxolotlStore.ID + " INTEGER, "
|
+ SQLiteAxolotlStore.ID + " INTEGER, "
|
||||||
|
@ -559,6 +560,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
if (oldVersion < 47 && newVersion >= 47) {
|
if (oldVersion < 47 && newVersion >= 47) {
|
||||||
db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " + Contact.PRESENCE_NAME + " TEXT");
|
db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " + Contact.PRESENCE_NAME + " TEXT");
|
||||||
}
|
}
|
||||||
|
if (oldVersion < 48 && newVersion >= 48) {
|
||||||
|
db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " + Contact.RTP_CAPABILITY + " TEXT");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void canonicalizeJids(SQLiteDatabase db) {
|
private void canonicalizeJids(SQLiteDatabase db) {
|
||||||
|
|
|
@ -358,10 +358,10 @@ public class XmppConnectionService extends Service {
|
||||||
syncDirtyContacts(account);
|
syncDirtyContacts(account);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private AtomicLong mLastExpiryRun = new AtomicLong(0);
|
private final AtomicLong mLastExpiryRun = new AtomicLong(0);
|
||||||
private SecureRandom mRandom;
|
private SecureRandom mRandom;
|
||||||
private LruCache<Pair<String, String>, ServiceDiscoveryResult> discoCache = new LruCache<>(20);
|
private final LruCache<Pair<String, String>, ServiceDiscoveryResult> discoCache = new LruCache<>(20);
|
||||||
private OnStatusChanged statusListener = new OnStatusChanged() {
|
private final OnStatusChanged statusListener = new OnStatusChanged() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStatusChanged(final Account account) {
|
public void onStatusChanged(final Account account) {
|
||||||
|
@ -4552,6 +4552,10 @@ public class XmppConnectionService extends Service {
|
||||||
final ServiceDiscoveryResult disco = getCachedServiceDiscoveryResult(key);
|
final ServiceDiscoveryResult disco = getCachedServiceDiscoveryResult(key);
|
||||||
if (disco != null) {
|
if (disco != null) {
|
||||||
presence.setServiceDiscoveryResult(disco);
|
presence.setServiceDiscoveryResult(disco);
|
||||||
|
final Contact contact = account.getRoster().getContact(jid);
|
||||||
|
if (contact.refreshRtpCapability()) {
|
||||||
|
syncRoster(account);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (account.inProgressDiscoFetches.contains(key)) {
|
if (account.inProgressDiscoFetches.contains(key)) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": skipping duplicate disco request for " + key.second + " to " + jid);
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": skipping duplicate disco request for " + key.second + " to " + jid);
|
||||||
|
@ -4585,12 +4589,21 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectServiceDiscoveryResult(Roster roster, String hash, String ver, ServiceDiscoveryResult disco) {
|
private void injectServiceDiscoveryResult(Roster roster, String hash, String ver, ServiceDiscoveryResult disco) {
|
||||||
|
boolean rosterNeedsSync = false;
|
||||||
for (final Contact contact : roster.getContacts()) {
|
for (final Contact contact : roster.getContacts()) {
|
||||||
|
boolean serviceDiscoverySet = false;
|
||||||
for (final Presence presence : contact.getPresences().getPresences()) {
|
for (final Presence presence : contact.getPresences().getPresences()) {
|
||||||
if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) {
|
if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) {
|
||||||
presence.setServiceDiscoveryResult(disco);
|
presence.setServiceDiscoveryResult(disco);
|
||||||
|
serviceDiscoverySet = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (serviceDiscoverySet) {
|
||||||
|
rosterNeedsSync |= contact.refreshRtpCapability();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rosterNeedsSync) {
|
||||||
|
syncRoster(roster.getAccount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package eu.siacs.conversations.xmpp.jingle;
|
package eu.siacs.conversations.xmpp.jingle;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -20,7 +22,7 @@ public class RtpCapability {
|
||||||
Namespace.JINGLE_APPS_RTP,
|
Namespace.JINGLE_APPS_RTP,
|
||||||
Namespace.JINGLE_APPS_DTLS
|
Namespace.JINGLE_APPS_DTLS
|
||||||
);
|
);
|
||||||
private static List<String> VIDEO_REQUIREMENTS = Arrays.asList(
|
private static final List<String> VIDEO_REQUIREMENTS = Arrays.asList(
|
||||||
Namespace.JINGLE_FEATURE_AUDIO,
|
Namespace.JINGLE_FEATURE_AUDIO,
|
||||||
Namespace.JINGLE_FEATURE_VIDEO
|
Namespace.JINGLE_FEATURE_VIDEO
|
||||||
);
|
);
|
||||||
|
@ -42,7 +44,7 @@ public class RtpCapability {
|
||||||
public static String[] filterPresences(final Contact contact, Capability required) {
|
public static String[] filterPresences(final Contact contact, Capability required) {
|
||||||
final Presences presences = contact.getPresences();
|
final Presences presences = contact.getPresences();
|
||||||
final ArrayList<String> resources = new ArrayList<>();
|
final ArrayList<String> resources = new ArrayList<>();
|
||||||
for(final Map.Entry<String,Presence> presence : presences.getPresencesMap().entrySet()) {
|
for (final Map.Entry<String, Presence> presence : presences.getPresencesMap().entrySet()) {
|
||||||
final Capability capability = check(presence.getValue());
|
final Capability capability = check(presence.getValue());
|
||||||
if (capability == Capability.NONE) {
|
if (capability == Capability.NONE) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -55,9 +57,16 @@ public class RtpCapability {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Capability check(final Contact contact) {
|
public static Capability check(final Contact contact) {
|
||||||
|
return check(contact, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Capability check(final Contact contact, final boolean allowFallback) {
|
||||||
final Presences presences = contact.getPresences();
|
final Presences presences = contact.getPresences();
|
||||||
|
if (presences.size() == 0 && allowFallback) {
|
||||||
|
return contact.getRtpCapability();
|
||||||
|
}
|
||||||
Capability result = Capability.NONE;
|
Capability result = Capability.NONE;
|
||||||
for(Presence presence : presences.getPresences()) {
|
for (final Presence presence : presences.getPresences()) {
|
||||||
Capability capability = check(presence);
|
Capability capability = check(presence);
|
||||||
if (capability == Capability.VIDEO) {
|
if (capability == Capability.VIDEO) {
|
||||||
result = capability;
|
result = capability;
|
||||||
|
@ -69,7 +78,18 @@ public class RtpCapability {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Capability {
|
public enum Capability {
|
||||||
NONE, AUDIO, VIDEO
|
NONE, AUDIO, VIDEO;
|
||||||
|
|
||||||
|
public static Capability of(String value) {
|
||||||
|
if (Strings.isNullOrEmpty(value)) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return valueOf(value);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue