use empty string instead of null for 'no node' and 'no resource'
This commit is contained in:
parent
90e613f94e
commit
1a09b3ed05
|
@ -2,7 +2,7 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "a521ff7a3e16cca9f6cbfe51241ec021",
|
||||
"identityHash": "b28e01dcbb5d9774a4b36783d0db6c73",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "account",
|
||||
|
@ -427,7 +427,7 @@
|
|||
},
|
||||
{
|
||||
"tableName": "disco_ext_field_value",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `fieldId` INTEGER NOT NULL, `value` TEXT, FOREIGN KEY(`fieldId`) REFERENCES `disco_ext`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `fieldId` INTEGER NOT NULL, `value` TEXT, FOREIGN KEY(`fieldId`) REFERENCES `disco_ext_field`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
|
@ -467,7 +467,7 @@
|
|||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "disco_ext",
|
||||
"table": "disco_ext_field",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
|
@ -601,7 +601,7 @@
|
|||
},
|
||||
{
|
||||
"tableName": "disco_item",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `address` TEXT NOT NULL, `node` TEXT, `parent` TEXT, `discoId` INTEGER, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`discoId`) REFERENCES `disco`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `address` TEXT NOT NULL, `node` TEXT NOT NULL, `parent` TEXT, `discoId` INTEGER, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`discoId`) REFERENCES `disco`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
|
@ -625,7 +625,7 @@
|
|||
"fieldPath": "node",
|
||||
"columnName": "node",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "parent",
|
||||
|
@ -975,7 +975,7 @@
|
|||
},
|
||||
{
|
||||
"tableName": "presence",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `address` TEXT NOT NULL, `resource` TEXT, `type` TEXT, `show` TEXT, `status` TEXT, `vCardPhoto` TEXT, `occupantId` TEXT, `mucUserAffiliation` TEXT, `mucUserRole` TEXT, `mucUserJid` TEXT, `mucUserSelf` INTEGER NOT NULL, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `address` TEXT NOT NULL, `resource` TEXT NOT NULL, `type` TEXT, `show` TEXT, `status` TEXT, `vCardPhoto` TEXT, `occupantId` TEXT, `mucUserAffiliation` TEXT, `mucUserRole` TEXT, `mucUserJid` TEXT, `mucUserSelf` INTEGER NOT NULL, `discoId` INTEGER, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`discoId`) REFERENCES `disco`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
|
@ -999,7 +999,7 @@
|
|||
"fieldPath": "resource",
|
||||
"columnName": "resource",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
|
@ -1054,6 +1054,12 @@
|
|||
"columnName": "mucUserSelf",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "discoId",
|
||||
"columnName": "discoId",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
|
@ -1073,6 +1079,15 @@
|
|||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_presence_accountId_address_resource` ON `${TABLE_NAME}` (`accountId`, `address`, `resource`)"
|
||||
},
|
||||
{
|
||||
"name": "index_presence_discoId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"discoId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_presence_discoId` ON `${TABLE_NAME}` (`discoId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
|
@ -1086,6 +1101,17 @@
|
|||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "disco",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"discoId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1310,7 +1336,7 @@
|
|||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a521ff7a3e16cca9f6cbfe51241ec021')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b28e01dcbb5d9774a4b36783d0db6c73')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -72,7 +72,7 @@ public class Element {
|
|||
}
|
||||
|
||||
public <E extends Extension> E getExtension(final Class<E> clazz) {
|
||||
final var extension = Iterables.find(this.children, clazz::isInstance);
|
||||
final var extension = Iterables.find(this.children, clazz::isInstance, null);
|
||||
if (extension == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package im.conversations.android.database.dao;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Transaction;
|
||||
import androidx.room.Upsert;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Collections2;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
import im.conversations.android.database.entity.DiscoEntity;
|
||||
|
@ -15,6 +18,7 @@ import im.conversations.android.database.entity.DiscoFeatureEntity;
|
|||
import im.conversations.android.database.entity.DiscoIdentityEntity;
|
||||
import im.conversations.android.database.entity.DiscoItemEntity;
|
||||
import im.conversations.android.database.model.Account;
|
||||
import im.conversations.android.xmpp.Entity;
|
||||
import im.conversations.android.xmpp.EntityCapabilities;
|
||||
import im.conversations.android.xmpp.EntityCapabilities2;
|
||||
import im.conversations.android.xmpp.model.data.Data;
|
||||
|
@ -43,12 +47,18 @@ public abstract class DiscoDao {
|
|||
protected abstract void deleteNonExistentDiscoItems(
|
||||
final long account, final Jid parent, final Collection<Jid> existent);
|
||||
|
||||
@Query(
|
||||
"UPDATE presence SET discoId=:discoId WHERE accountId=:account AND address=:address"
|
||||
+ " AND resource=:resource")
|
||||
protected abstract void updateDiscoIdInPresence(
|
||||
long account, Jid address, String resource, long discoId);
|
||||
|
||||
@Insert
|
||||
protected abstract void insertDiscoFieldValues(
|
||||
Collection<DiscoExtensionFieldValueEntity> value);
|
||||
|
||||
@Upsert(entity = DiscoItemEntity.class)
|
||||
protected abstract void insert(DiscoItemWithDiscoId item);
|
||||
protected abstract void updateDiscoIdInDiscoItem(DiscoItemWithDiscoId item);
|
||||
|
||||
@Insert
|
||||
protected abstract long insert(DiscoEntity entity);
|
||||
|
@ -60,19 +70,20 @@ public abstract class DiscoDao {
|
|||
protected abstract long insert(DiscoExtensionFieldEntity entity);
|
||||
|
||||
@Transaction
|
||||
public void set(final Account account, final Jid parent, final Collection<Item> items) {
|
||||
public void set(
|
||||
final Account account, final Entity.DiscoItem parent, final Collection<Item> items) {
|
||||
final var entities =
|
||||
Collections2.transform(items, i -> DiscoItemWithParent.of(account.id, parent, i));
|
||||
insertDiscoItems(entities);
|
||||
deleteNonExistentDiscoItems(
|
||||
account.id, parent, Collections2.transform(items, Item::getJid));
|
||||
account.id, parent.address, Collections2.transform(items, Item::getJid));
|
||||
}
|
||||
|
||||
@Transaction
|
||||
public boolean set(
|
||||
final Account account,
|
||||
final Jid address,
|
||||
final String node,
|
||||
final Entity entity,
|
||||
@Nullable final String node,
|
||||
final EntityCapabilities.Hash capsHash) {
|
||||
final Long existingDiscoId;
|
||||
if (capsHash instanceof EntityCapabilities2.EntityCaps2Hash) {
|
||||
|
@ -85,14 +96,31 @@ public abstract class DiscoDao {
|
|||
if (existingDiscoId == null) {
|
||||
return false;
|
||||
}
|
||||
insert(DiscoItemWithDiscoId.of(account.id, address, node, existingDiscoId));
|
||||
updateDiscoId(account.id, entity, node, existingDiscoId);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void updateDiscoId(
|
||||
final long account,
|
||||
final Entity entity,
|
||||
@Nullable final String node,
|
||||
final long discoId) {
|
||||
if (entity instanceof Entity.DiscoItem) {
|
||||
updateDiscoIdInDiscoItem(
|
||||
DiscoItemWithDiscoId.of(account, (Entity.DiscoItem) entity, node, discoId));
|
||||
} else if (entity instanceof Entity.Presence) {
|
||||
updateDiscoIdInPresence(
|
||||
account,
|
||||
entity.address.asBareJid(),
|
||||
Strings.nullToEmpty(entity.address.getResource()),
|
||||
discoId);
|
||||
}
|
||||
}
|
||||
|
||||
@Transaction
|
||||
public void set(
|
||||
final Account account,
|
||||
final Jid address,
|
||||
final Entity entity,
|
||||
final String node,
|
||||
final byte[] capsHash,
|
||||
final byte[] caps2HashSha256,
|
||||
|
@ -100,7 +128,7 @@ public abstract class DiscoDao {
|
|||
|
||||
final Long existingDiscoId = getDiscoId(account.id, caps2HashSha256);
|
||||
if (existingDiscoId != null) {
|
||||
insert(DiscoItemWithDiscoId.of(account.id, address, node, existingDiscoId));
|
||||
updateDiscoId(account.id, entity, node, existingDiscoId);
|
||||
return;
|
||||
}
|
||||
final long discoId = insert(DiscoEntity.of(account.id, capsHash, caps2HashSha256));
|
||||
|
@ -125,6 +153,7 @@ public abstract class DiscoDao {
|
|||
v -> DiscoExtensionFieldValueEntity.of(fieldId, v.getContent())));
|
||||
}
|
||||
}
|
||||
updateDiscoId(account.id, entity, node, discoId);
|
||||
}
|
||||
|
||||
@Query("SELECT id FROM disco WHERE accountId=:accountId AND caps2HashSha256=:caps2HashSha256")
|
||||
|
@ -141,32 +170,35 @@ public abstract class DiscoDao {
|
|||
|
||||
public static class DiscoItemWithParent {
|
||||
public long accountId;
|
||||
public Jid address;
|
||||
public String node;
|
||||
public Jid parent;
|
||||
public @NonNull Jid address;
|
||||
public @NonNull String node;
|
||||
public @Nullable Jid parent;
|
||||
|
||||
public static DiscoItemWithParent of(
|
||||
final long account, final Jid parent, final Item item) {
|
||||
final long account, Entity.DiscoItem parent, final Item item) {
|
||||
final var entity = new DiscoItemWithParent();
|
||||
entity.accountId = account;
|
||||
entity.address = item.getJid();
|
||||
entity.node = item.getNode();
|
||||
entity.parent = parent;
|
||||
entity.node = Strings.nullToEmpty(item.getNode());
|
||||
entity.parent = parent.address;
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DiscoItemWithDiscoId {
|
||||
public long accountId;
|
||||
public Jid address;
|
||||
public String node;
|
||||
public @NonNull Jid address;
|
||||
public @NonNull String node;
|
||||
public long discoId;
|
||||
|
||||
public static DiscoItemWithDiscoId of(
|
||||
final long account, final Jid address, final String node, final long discoId) {
|
||||
final long account,
|
||||
final Entity.DiscoItem discoItem,
|
||||
@NonNull final String node,
|
||||
final long discoId) {
|
||||
final var entity = new DiscoItemWithDiscoId();
|
||||
entity.accountId = account;
|
||||
entity.address = address;
|
||||
entity.address = discoItem.address;
|
||||
entity.node = node;
|
||||
entity.discoId = discoId;
|
||||
return entity;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package im.conversations.android.database.dao;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Upsert;
|
||||
|
@ -28,12 +30,12 @@ public abstract class PresenceDao {
|
|||
abstract void insert(PresenceEntity entity);
|
||||
|
||||
public void set(
|
||||
Account account,
|
||||
Jid address,
|
||||
String resource,
|
||||
PresenceType type,
|
||||
PresenceShow show,
|
||||
String status) {
|
||||
@NonNull final Account account,
|
||||
@NonNull final Jid address,
|
||||
@Nullable final String resource,
|
||||
@Nullable final PresenceType type,
|
||||
@Nullable final PresenceShow show,
|
||||
@Nullable final String status) {
|
||||
if (resource == null
|
||||
&& Arrays.asList(PresenceType.ERROR, PresenceType.UNAVAILABLE).contains(type)) {
|
||||
deletePresences(account.id, address);
|
||||
|
|
|
@ -10,7 +10,7 @@ import androidx.room.PrimaryKey;
|
|||
tableName = "disco_ext_field_value",
|
||||
foreignKeys =
|
||||
@ForeignKey(
|
||||
entity = DiscoExtensionEntity.class,
|
||||
entity = DiscoExtensionFieldEntity.class,
|
||||
parentColumns = {"id"},
|
||||
childColumns = {"fieldId"},
|
||||
onDelete = ForeignKey.CASCADE),
|
||||
|
@ -25,6 +25,9 @@ public class DiscoExtensionFieldValueEntity {
|
|||
public String value;
|
||||
|
||||
public static DiscoExtensionFieldValueEntity of(long fieldId, final String value) {
|
||||
return null;
|
||||
final var entity = new DiscoExtensionFieldValueEntity();
|
||||
entity.fieldId = fieldId;
|
||||
entity.value = value;
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ public class DiscoItemEntity {
|
|||
|
||||
@NonNull Jid address;
|
||||
|
||||
@Nullable public String node;
|
||||
@NonNull public String node;
|
||||
|
||||
@Nullable public Jid parent;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.room.Entity;
|
|||
import androidx.room.ForeignKey;
|
||||
import androidx.room.Index;
|
||||
import androidx.room.PrimaryKey;
|
||||
import com.google.common.base.Strings;
|
||||
import eu.siacs.conversations.entities.MucOptions;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
import im.conversations.android.database.model.PresenceShow;
|
||||
|
@ -13,16 +14,23 @@ import im.conversations.android.database.model.PresenceType;
|
|||
|
||||
@Entity(
|
||||
tableName = "presence",
|
||||
foreignKeys =
|
||||
foreignKeys = {
|
||||
@ForeignKey(
|
||||
entity = AccountEntity.class,
|
||||
parentColumns = {"id"},
|
||||
childColumns = {"accountId"},
|
||||
onDelete = ForeignKey.CASCADE),
|
||||
@ForeignKey(
|
||||
entity = DiscoEntity.class,
|
||||
parentColumns = {"id"},
|
||||
childColumns = {"discoId"},
|
||||
onDelete = ForeignKey.CASCADE)
|
||||
},
|
||||
indices = {
|
||||
@Index(
|
||||
value = {"accountId", "address", "resource"},
|
||||
unique = true)
|
||||
unique = true),
|
||||
@Index(value = {"discoId"})
|
||||
})
|
||||
public class PresenceEntity {
|
||||
|
||||
|
@ -33,7 +41,7 @@ public class PresenceEntity {
|
|||
|
||||
@NonNull public Jid address;
|
||||
|
||||
@Nullable public String resource;
|
||||
@NonNull public String resource;
|
||||
|
||||
@Nullable public PresenceType type;
|
||||
|
||||
|
@ -54,17 +62,19 @@ public class PresenceEntity {
|
|||
// set to true if presence has status code 110 (this means we are online)
|
||||
public boolean mucUserSelf;
|
||||
|
||||
public Long discoId;
|
||||
|
||||
public static PresenceEntity of(
|
||||
long account,
|
||||
Jid address,
|
||||
String resource,
|
||||
@Nullable String resource,
|
||||
PresenceType type,
|
||||
PresenceShow show,
|
||||
String status) {
|
||||
final var entity = new PresenceEntity();
|
||||
entity.accountId = account;
|
||||
entity.address = address;
|
||||
entity.resource = resource;
|
||||
entity.resource = Strings.nullToEmpty(resource);
|
||||
entity.type = type;
|
||||
entity.show = show;
|
||||
entity.status = status;
|
||||
|
|
|
@ -1,4 +1,34 @@
|
|||
package im.conversations.android.xmpp;
|
||||
|
||||
public class Entity {
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
|
||||
public abstract class Entity {
|
||||
|
||||
public final Jid address;
|
||||
|
||||
private Entity(final Jid address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public static class DiscoItem extends Entity {
|
||||
|
||||
private DiscoItem(Jid address) {
|
||||
super(address);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Presence extends Entity {
|
||||
|
||||
private Presence(Jid address) {
|
||||
super(address);
|
||||
}
|
||||
}
|
||||
|
||||
public static Presence presence(final Jid address) {
|
||||
return new Presence(address);
|
||||
}
|
||||
|
||||
public static DiscoItem discoItem(final Jid address) {
|
||||
return new DiscoItem(address);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1735,10 +1735,23 @@ public class XmppConnection implements Runnable {
|
|||
final Element bind = packet.findChild("bind");
|
||||
if (bind != null && packet.getType() == IqPacket.TYPE.RESULT) {
|
||||
isBound = true;
|
||||
final Element jid = bind.findChild("jid");
|
||||
if (jid != null && jid.getContent() != null) {
|
||||
final String jid = bind.findChildContent("jid");
|
||||
if (Strings.isNullOrEmpty(jid)) {
|
||||
throw new StateChangingError(ConnectionState.BIND_FAILURE);
|
||||
}
|
||||
final Jid assignedJid;
|
||||
try {
|
||||
final Jid assignedJid = Jid.ofEscaped(jid.getContent());
|
||||
assignedJid = Jid.ofEscaped(jid);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
Log.d(
|
||||
Config.LOGTAG,
|
||||
account.address
|
||||
+ ": server reported invalid jid ("
|
||||
+ jid
|
||||
+ ") on bind");
|
||||
throw new StateChangingError(ConnectionState.BIND_FAILURE);
|
||||
}
|
||||
|
||||
if (!account.address.getDomain().equals(assignedJid.getDomain())) {
|
||||
Log.d(
|
||||
Config.LOGTAG,
|
||||
|
@ -1749,29 +1762,13 @@ public class XmppConnection implements Runnable {
|
|||
}
|
||||
setConnectionAddress(assignedJid);
|
||||
if (streamFeatures.hasChild("session")
|
||||
&& !streamFeatures
|
||||
.findChild("session")
|
||||
.hasChild("optional")) {
|
||||
&& !streamFeatures.findChild("session").hasChild("optional")) {
|
||||
sendStartSession();
|
||||
} else {
|
||||
enableStreamManagement();
|
||||
sendPostBindInitialization(false);
|
||||
}
|
||||
return;
|
||||
} catch (final IllegalArgumentException e) {
|
||||
Log.d(
|
||||
Config.LOGTAG,
|
||||
account.address
|
||||
+ ": server reported invalid jid ("
|
||||
+ jid.getContent()
|
||||
+ ") on bind");
|
||||
}
|
||||
} else {
|
||||
Log.d(
|
||||
Config.LOGTAG,
|
||||
account.address
|
||||
+ ": disconnecting because of bind failure. (no jid)");
|
||||
}
|
||||
} else {
|
||||
Log.d(
|
||||
Config.LOGTAG,
|
||||
|
@ -1885,14 +1882,14 @@ public class XmppConnection implements Runnable {
|
|||
final var discoManager = getManager(DiscoManager.class);
|
||||
|
||||
final var nodeHash = this.streamFeatures.getCapabilities();
|
||||
final var domainDiscoItem = Entity.discoItem(account.address.getDomain());
|
||||
if (nodeHash != null) {
|
||||
discoFutures.add(
|
||||
discoManager.info(account.address.getDomain(), nodeHash.node, nodeHash.hash));
|
||||
discoFutures.add(discoManager.info(domainDiscoItem, nodeHash.node, nodeHash.hash));
|
||||
} else {
|
||||
discoFutures.add(discoManager.info(account.address.getDomain()));
|
||||
discoFutures.add(discoManager.info(domainDiscoItem));
|
||||
}
|
||||
discoFutures.add(discoManager.info(account.address));
|
||||
discoFutures.add(discoManager.itemsWithInfo(account.address.getDomain()));
|
||||
discoFutures.add(discoManager.info(Entity.discoItem(account.address)));
|
||||
discoFutures.add(discoManager.itemsWithInfo(domainDiscoItem));
|
||||
|
||||
final var discoFuture =
|
||||
Futures.withTimeout(
|
||||
|
@ -1912,6 +1909,7 @@ public class XmppConnection implements Runnable {
|
|||
|
||||
@Override
|
||||
public void onFailure(@NonNull Throwable t) {
|
||||
Log.d(Config.LOGTAG, "unable to fetch disco foo " + t);
|
||||
// TODO reset stream ID so we get a proper connect next time
|
||||
finalizeBind();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||
import im.conversations.android.xmpp.Entity;
|
||||
import im.conversations.android.xmpp.EntityCapabilities;
|
||||
import im.conversations.android.xmpp.EntityCapabilities2;
|
||||
import im.conversations.android.xmpp.XmppConnection;
|
||||
|
@ -24,12 +25,12 @@ public class DiscoManager extends AbstractManager {
|
|||
super(context, connection);
|
||||
}
|
||||
|
||||
public ListenableFuture<InfoQuery> info(final Jid entity) {
|
||||
public ListenableFuture<InfoQuery> info(final Entity entity) {
|
||||
return info(entity, null);
|
||||
}
|
||||
|
||||
public ListenableFuture<Void> info(
|
||||
final Jid entity, @Nullable final String node, final EntityCapabilities.Hash hash) {
|
||||
final Entity entity, @Nullable final String node, final EntityCapabilities.Hash hash) {
|
||||
final String capabilityNode = hash.capabilityNode(node);
|
||||
if (getDatabase().discoDao().set(getAccount(), entity, capabilityNode, hash)) {
|
||||
return Futures.immediateFuture(null);
|
||||
|
@ -38,9 +39,9 @@ public class DiscoManager extends AbstractManager {
|
|||
info(entity, capabilityNode), f -> null, MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
public ListenableFuture<InfoQuery> info(final Jid entity, final String node) {
|
||||
public ListenableFuture<InfoQuery> info(final Entity entity, final String node) {
|
||||
final var iqRequest = new IqPacket(IqPacket.TYPE.GET);
|
||||
iqRequest.setTo(entity);
|
||||
iqRequest.setTo(entity.address);
|
||||
final var infoQueryRequest = new InfoQuery();
|
||||
if (node != null) {
|
||||
infoQueryRequest.setNode(node);
|
||||
|
@ -70,9 +71,9 @@ public class DiscoManager extends AbstractManager {
|
|||
MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
public ListenableFuture<Collection<Item>> items(final Jid entity) {
|
||||
public ListenableFuture<Collection<Item>> items(final Entity.DiscoItem entity) {
|
||||
final var iqPacket = new IqPacket(IqPacket.TYPE.GET);
|
||||
iqPacket.setTo(entity);
|
||||
iqPacket.setTo(entity.address);
|
||||
iqPacket.addChild(new ItemsQuery());
|
||||
final var future = connection.sendIqPacket(iqPacket);
|
||||
return Futures.transform(
|
||||
|
@ -91,14 +92,16 @@ public class DiscoManager extends AbstractManager {
|
|||
MoreExecutors.directExecutor());
|
||||
}
|
||||
|
||||
public ListenableFuture<List<InfoQuery>> itemsWithInfo(final Jid entity) {
|
||||
public ListenableFuture<List<InfoQuery>> itemsWithInfo(final Entity.DiscoItem entity) {
|
||||
final var itemsFutures = items(entity);
|
||||
return Futures.transformAsync(
|
||||
itemsFutures,
|
||||
items -> {
|
||||
// TODO filter out items with empty jid
|
||||
final var filtered =
|
||||
Collections2.filter(items, i -> Objects.nonNull(i.getJid()));
|
||||
Collection<ListenableFuture<InfoQuery>> infoFutures =
|
||||
Collections2.transform(items, i -> info(i.getJid(), i.getNode()));
|
||||
Collections2.transform(
|
||||
filtered, i -> info(Entity.discoItem(i.getJid()), i.getNode()));
|
||||
return Futures.allAsList(infoFutures);
|
||||
},
|
||||
MoreExecutors.directExecutor());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package im.conversations.android.xmpp.model.disco.items;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
import im.conversations.android.annotation.XmlElement;
|
||||
import im.conversations.android.xmpp.model.Extension;
|
||||
|
@ -14,7 +15,7 @@ public class Item extends Extension {
|
|||
return getAttributeAsJid("jid");
|
||||
}
|
||||
|
||||
public String getNode() {
|
||||
public @Nullable String getNode() {
|
||||
return this.getAttribute("node");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
|
||||
import im.conversations.android.database.model.PresenceShow;
|
||||
import im.conversations.android.database.model.PresenceType;
|
||||
import im.conversations.android.xmpp.Entity;
|
||||
import im.conversations.android.xmpp.XmppConnection;
|
||||
import im.conversations.android.xmpp.manager.DiscoManager;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -41,7 +42,8 @@ public class PresenceProcessor extends XmppConnection.Delegate implements Consum
|
|||
final var entity = presencePacket.getFrom();
|
||||
final var nodeHash = presencePacket.getCapabilities();
|
||||
if (nodeHash != null) {
|
||||
getManager(DiscoManager.class).info(entity, nodeHash.node, nodeHash.hash);
|
||||
getManager(DiscoManager.class)
|
||||
.info(Entity.presence(entity), nodeHash.node, nodeHash.hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue