remember last rtp capability

This commit is contained in:
Daniel Gultsch 2021-01-21 16:47:30 +01:00
parent e087b594ff
commit e711b3d294
6 changed files with 75 additions and 17 deletions

View file

@ -18,6 +18,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import eu.siacs.conversations.Config;
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.UIHelper;
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.Jid;
@ -46,6 +48,7 @@ public class Contact implements ListItem, Blockable {
public static final String LAST_PRESENCE = "last_presence";
public static final String LAST_TIME = "last_time";
public static final String GROUPS = "groups";
public static final String RTP_CAPABILITY = "rtpCapability";
private String accountUuid;
private String systemName;
private String serverName;
@ -64,11 +67,12 @@ public class Contact implements ListItem, Blockable {
private boolean mActive = false;
private long mLastseen = 0;
private String mLastPresence = null;
private RtpCapability.Capability rtpCapability;
public Contact(final String account, final String systemName, final String serverName, final String presenceName,
final Jid jid, final int subscription, final String photoUri,
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.systemName = systemName;
this.serverName = serverName;
@ -96,6 +100,7 @@ public class Contact implements ListItem, Blockable {
}
this.mLastseen = lastseen;
this.mLastPresence = presence;
this.rtpCapability = rtpCapability;
}
public Contact(final Jid jid) {
@ -129,7 +134,8 @@ public class Contact implements ListItem, Blockable {
cursor.getString(cursor.getColumnIndex(AVATAR)),
cursor.getLong(cursor.getColumnIndex(LAST_TIME)),
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() {
@ -234,6 +240,7 @@ public class Contact implements ListItem, Blockable {
values.put(LAST_PRESENCE, mLastPresence);
values.put(LAST_TIME, mLastseen);
values.put(GROUPS, groups.toString());
values.put(RTP_CAPABILITY, rtpCapability == null ? null : rtpCapability.toString());
return values;
}
}
@ -573,7 +580,18 @@ public class Contact implements ListItem, Blockable {
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 FROM = 1;
public static final int ASKING = 2;

View file

@ -7,7 +7,7 @@ import java.util.Locale;
import eu.siacs.conversations.xml.Element;
public class Presence implements Comparable {
public class Presence implements Comparable<Presence> {
public enum Status {
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);
}
public int compareTo(@NonNull Object other) {
public int compareTo(@NonNull Presence other) {
return this.status.compareTo(((Presence)other).status);
}

View file

@ -136,6 +136,9 @@ public class Presences {
public boolean anySupport(final String namespace) {
synchronized (this.presences) {
if (this.presences.size() == 0) {
return true;
}
for (Presence presence : this.presences.values()) {
ServiceDiscoveryResult disco = presence.getServiceDiscoveryResult();
if (disco != null && disco.getFeatures().contains(namespace)) {

View file

@ -63,9 +63,9 @@ import eu.siacs.conversations.xmpp.Jid;
public class DatabaseBackend extends SQLiteOpenHelper {
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 String CREATE_CONTATCS_STATEMENT = "create table "
private static final String CREATE_CONTATCS_STATEMENT = "create table "
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
+ Contact.SERVERNAME + " TEXT, " + Contact.SYSTEMNAME + " TEXT,"
+ Contact.PRESENCE_NAME + " TEXT,"
@ -73,12 +73,13 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ Contact.PHOTOURI + " TEXT," + Contact.OPTIONS + " NUMBER,"
+ Contact.SYSTEMACCOUNT + " NUMBER, " + Contact.AVATAR + " TEXT, "
+ Contact.LAST_PRESENCE + " TEXT, " + Contact.LAST_TIME + " NUMBER, "
+ Contact.RTP_CAPABILITY + " TEXT,"
+ Contact.GROUPS + " TEXT, FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES "
+ Account.TABLENAME + "(" + Account.UUID
+ ") ON DELETE CASCADE, UNIQUE(" + Contact.ACCOUNT + ", "
+ 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.HASH + " TEXT, "
+ ServiceDiscoveryResult.VER + " TEXT, "
@ -86,7 +87,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ "UNIQUE(" + ServiceDiscoveryResult.HASH + ", "
+ 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.UUID + " TEXT, "
+ PresenceTemplate.LAST_USED + " NUMBER,"
@ -94,7 +95,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ PresenceTemplate.STATUS + " TEXT,"
+ "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.ACCOUNT + " TEXT, "
+ SQLiteAxolotlStore.ID + " INTEGER, "
@ -559,6 +560,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
if (oldVersion < 47 && newVersion >= 47) {
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) {

View file

@ -358,10 +358,10 @@ public class XmppConnectionService extends Service {
syncDirtyContacts(account);
}
};
private AtomicLong mLastExpiryRun = new AtomicLong(0);
private final AtomicLong mLastExpiryRun = new AtomicLong(0);
private SecureRandom mRandom;
private LruCache<Pair<String, String>, ServiceDiscoveryResult> discoCache = new LruCache<>(20);
private OnStatusChanged statusListener = new OnStatusChanged() {
private final LruCache<Pair<String, String>, ServiceDiscoveryResult> discoCache = new LruCache<>(20);
private final OnStatusChanged statusListener = new OnStatusChanged() {
@Override
public void onStatusChanged(final Account account) {
@ -4552,6 +4552,10 @@ public class XmppConnectionService extends Service {
final ServiceDiscoveryResult disco = getCachedServiceDiscoveryResult(key);
if (disco != null) {
presence.setServiceDiscoveryResult(disco);
final Contact contact = account.getRoster().getContact(jid);
if (contact.refreshRtpCapability()) {
syncRoster(account);
}
} else {
if (account.inProgressDiscoFetches.contains(key)) {
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) {
boolean rosterNeedsSync = false;
for (final Contact contact : roster.getContacts()) {
boolean serviceDiscoverySet = false;
for (final Presence presence : contact.getPresences().getPresences()) {
if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) {
presence.setServiceDiscoveryResult(disco);
serviceDiscoverySet = true;
}
}
if (serviceDiscoverySet) {
rosterNeedsSync |= contact.refreshRtpCapability();
}
}
if (rosterNeedsSync) {
syncRoster(roster.getAccount());
}
}

View file

@ -1,5 +1,7 @@
package eu.siacs.conversations.xmpp.jingle;
import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -20,7 +22,7 @@ public class RtpCapability {
Namespace.JINGLE_APPS_RTP,
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_VIDEO
);
@ -55,9 +57,16 @@ public class RtpCapability {
}
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();
if (presences.size() == 0 && allowFallback) {
return contact.getRtpCapability();
}
Capability result = Capability.NONE;
for(Presence presence : presences.getPresences()) {
for (final Presence presence : presences.getPresences()) {
Capability capability = check(presence);
if (capability == Capability.VIDEO) {
result = capability;
@ -69,7 +78,18 @@ public class RtpCapability {
}
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;
}
}
}
}