fixed service discovery by properly storing and checking identities
This commit is contained in:
parent
82daf849aa
commit
5ea1c547d5
|
@ -468,7 +468,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
} else {
|
} else {
|
||||||
this.mServerInfoSm.setText(R.string.server_info_unavailable);
|
this.mServerInfoSm.setText(R.string.server_info_unavailable);
|
||||||
}
|
}
|
||||||
if (features.pubsub()) {
|
if (features.pep()) {
|
||||||
this.mServerInfoPep.setText(R.string.server_info_available);
|
this.mServerInfoPep.setText(R.string.server_info_available);
|
||||||
} else {
|
} else {
|
||||||
this.mServerInfoPep.setText(R.string.server_info_unavailable);
|
this.mServerInfoPep.setText(R.string.server_info_unavailable);
|
||||||
|
|
|
@ -163,8 +163,7 @@ public class PublishProfilePictureActivity extends XmppActivity {
|
||||||
if (jid != null) {
|
if (jid != null) {
|
||||||
this.account = xmppConnectionService.findAccountByJid(jid);
|
this.account = xmppConnectionService.findAccountByJid(jid);
|
||||||
if (this.account.getXmppConnection() != null) {
|
if (this.account.getXmppConnection() != null) {
|
||||||
this.support = this.account.getXmppConnection()
|
this.support = this.account.getXmppConnection().getFeatures().pep();
|
||||||
.getFeatures().pubsub();
|
|
||||||
}
|
}
|
||||||
if (this.avatarUri == null) {
|
if (this.avatarUri == null) {
|
||||||
if (this.account.getAvatar() != null
|
if (this.account.getAvatar() != null
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class XmppConnection implements Runnable {
|
||||||
private boolean shouldBind = true;
|
private boolean shouldBind = true;
|
||||||
private boolean shouldAuthenticate = true;
|
private boolean shouldAuthenticate = true;
|
||||||
private Element streamFeatures;
|
private Element streamFeatures;
|
||||||
private final HashMap<String, List<String>> disco = new HashMap<>();
|
private final HashMap<Jid, Info> disco = new HashMap<>();
|
||||||
|
|
||||||
private String streamId = null;
|
private String streamId = null;
|
||||||
private int smVersion = 3;
|
private int smVersion = 3;
|
||||||
|
@ -334,6 +334,7 @@ public class XmppConnection implements Runnable {
|
||||||
} catch (final NumberFormatException ignored) {
|
} catch (final NumberFormatException ignored) {
|
||||||
}
|
}
|
||||||
sendServiceDiscoveryInfo(account.getServer());
|
sendServiceDiscoveryInfo(account.getServer());
|
||||||
|
sendServiceDiscoveryInfo(account.getJid().toBareJid());
|
||||||
sendServiceDiscoveryItems(account.getServer());
|
sendServiceDiscoveryItems(account.getServer());
|
||||||
sendInitialPing();
|
sendInitialPing();
|
||||||
} else if (nextTag.isStart("r")) {
|
} else if (nextTag.isStart("r")) {
|
||||||
|
@ -734,6 +735,7 @@ public class XmppConnection implements Runnable {
|
||||||
features.blockListRequested = false;
|
features.blockListRequested = false;
|
||||||
disco.clear();
|
disco.clear();
|
||||||
sendServiceDiscoveryInfo(account.getServer());
|
sendServiceDiscoveryInfo(account.getServer());
|
||||||
|
sendServiceDiscoveryInfo(account.getJid().toBareJid());
|
||||||
sendServiceDiscoveryItems(account.getServer());
|
sendServiceDiscoveryItems(account.getServer());
|
||||||
if (bindListener != null) {
|
if (bindListener != null) {
|
||||||
bindListener.onBind(account);
|
bindListener.onBind(account);
|
||||||
|
@ -741,34 +743,35 @@ public class XmppConnection implements Runnable {
|
||||||
sendInitialPing();
|
sendInitialPing();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendServiceDiscoveryInfo(final Jid server) {
|
private void sendServiceDiscoveryInfo(final Jid jid) {
|
||||||
if (disco.containsKey(server.toDomainJid().toString())) {
|
if (disco.containsKey(jid)) {
|
||||||
if (account.getServer().equals(server.toDomainJid())) {
|
if (account.getServer().equals(jid)) {
|
||||||
enableAdvancedStreamFeatures();
|
enableAdvancedStreamFeatures();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final IqPacket iq = new IqPacket(IqPacket.TYPE.GET);
|
final IqPacket iq = new IqPacket(IqPacket.TYPE.GET);
|
||||||
iq.setTo(server.toDomainJid());
|
iq.setTo(jid);
|
||||||
iq.query("http://jabber.org/protocol/disco#info");
|
iq.query("http://jabber.org/protocol/disco#info");
|
||||||
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
final List<Element> elements = packet.query().getChildren();
|
final List<Element> elements = packet.query().getChildren();
|
||||||
final List<String> features = new ArrayList<>();
|
final Info info = new Info();
|
||||||
for (final Element element : elements) {
|
for (final Element element : elements) {
|
||||||
if (element.getName().equals("identity")) {
|
if (element.getName().equals("identity")) {
|
||||||
if ("irc".equals(element.getAttribute("type"))) {
|
String type = element.getAttribute("type");
|
||||||
//add fake feature to not confuse irc and real muc
|
String category = element.getAttribute("category");
|
||||||
features.add("siacs:no:muc");
|
if (type != null && category != null) {
|
||||||
|
info.identities.add(new Pair<>(category,type));
|
||||||
}
|
}
|
||||||
} else if (element.getName().equals("feature")) {
|
} else if (element.getName().equals("feature")) {
|
||||||
features.add(element.getAttribute("var"));
|
info.features.add(element.getAttribute("var"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
disco.put(server.toDomainJid().toString(), features);
|
disco.put(jid, info);
|
||||||
|
|
||||||
if (account.getServer().equals(server.toDomainJid())) {
|
if (account.getServer().equals(jid)) {
|
||||||
enableAdvancedStreamFeatures();
|
enableAdvancedStreamFeatures();
|
||||||
for (final OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) {
|
for (final OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) {
|
||||||
listener.onAdvancedStreamFeaturesAvailable(account);
|
listener.onAdvancedStreamFeaturesAvailable(account);
|
||||||
|
@ -987,9 +990,9 @@ public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
public List<String> findDiscoItemsByFeature(final String feature) {
|
public List<String> findDiscoItemsByFeature(final String feature) {
|
||||||
final List<String> items = new ArrayList<>();
|
final List<String> items = new ArrayList<>();
|
||||||
for (final Entry<String, List<String>> cursor : disco.entrySet()) {
|
for (final Entry<Jid, Info> cursor : disco.entrySet()) {
|
||||||
if (cursor.getValue().contains(feature)) {
|
if (cursor.getValue().features.contains(feature)) {
|
||||||
items.add(cursor.getKey());
|
items.add(cursor.getKey().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
|
@ -1008,10 +1011,12 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMucServer() {
|
public String getMucServer() {
|
||||||
for (final Entry<String, List<String>> cursor : disco.entrySet()) {
|
for (final Entry<Jid, Info> cursor : disco.entrySet()) {
|
||||||
final List<String> value = cursor.getValue();
|
final Info value = cursor.getValue();
|
||||||
if (value.contains("http://jabber.org/protocol/muc") && !value.contains("jabber:iq:gateway") && !value.contains("siacs:no:muc")) {
|
if (value.features.contains("http://jabber.org/protocol/muc")
|
||||||
return cursor.getKey();
|
&& !value.features.contains("jabber:iq:gateway")
|
||||||
|
&& !value.identities.contains(new Pair<>("conference","irc"))) {
|
||||||
|
return cursor.getKey().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1066,6 +1071,11 @@ public class XmppConnection implements Runnable {
|
||||||
this.lastConnect = 0;
|
this.lastConnect = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class Info {
|
||||||
|
public final ArrayList<String> features = new ArrayList<>();
|
||||||
|
public final ArrayList<Pair<String,String>> identities = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
public class Features {
|
public class Features {
|
||||||
XmppConnection connection;
|
XmppConnection connection;
|
||||||
private boolean carbonsEnabled = false;
|
private boolean carbonsEnabled = false;
|
||||||
|
@ -1077,8 +1087,8 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasDiscoFeature(final Jid server, final String feature) {
|
private boolean hasDiscoFeature(final Jid server, final String feature) {
|
||||||
return connection.disco.containsKey(server.toDomainJid().toString()) &&
|
return connection.disco.containsKey(server) &&
|
||||||
connection.disco.get(server.toDomainJid().toString()).contains(feature);
|
connection.disco.get(server).features.contains(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean carbons() {
|
public boolean carbons() {
|
||||||
|
@ -1094,24 +1104,35 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean sm() {
|
public boolean sm() {
|
||||||
return streamId != null;
|
return streamId != null
|
||||||
|
|| (connection.streamFeatures != null && connection.streamFeatures.hasChild("sm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean csi() {
|
public boolean csi() {
|
||||||
return connection.streamFeatures != null && connection.streamFeatures.hasChild("csi", "urn:xmpp:csi:0");
|
return connection.streamFeatures != null && connection.streamFeatures.hasChild("csi", "urn:xmpp:csi:0");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean pubsub() {
|
public boolean pep() {
|
||||||
return hasDiscoFeature(account.getServer(),
|
final Pair<String,String> needle = new Pair<>("pubsub","pep");
|
||||||
"http://jabber.org/protocol/pubsub#publish");
|
Info info = disco.get(account.getServer());
|
||||||
|
if (info != null && info.identities.contains(needle)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
info = disco.get(account.getJid().toBareJid());
|
||||||
|
return info != null && info.identities.contains(needle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean mam() {
|
public boolean mam() {
|
||||||
|
if (hasDiscoFeature(account.getJid().toBareJid(), "urn:xmpp:mam:0")) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
return hasDiscoFeature(account.getServer(), "urn:xmpp:mam:0");
|
return hasDiscoFeature(account.getServer(), "urn:xmpp:mam:0");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean advancedStreamFeaturesLoaded() {
|
public boolean advancedStreamFeaturesLoaded() {
|
||||||
return disco.containsKey(account.getServer().toString());
|
return disco.containsKey(account.getServer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean rosterVersioning() {
|
public boolean rosterVersioning() {
|
||||||
|
|
Loading…
Reference in a new issue