detect server identity and added muc-workaround for slack

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/Account.java               |  8 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 10 
src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java            | 36 
3 files changed, 49 insertions(+), 5 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Account.java 🔗

@@ -59,6 +59,14 @@ public class Account extends AbstractEntity {
 		return displayName;
 	}
 
+	public XmppConnection.Identity getServerIdentity() {
+		if (xmppConnection == null) {
+			return XmppConnection.Identity.UNKNOWN;
+		} else {
+			return xmppConnection.getServerIdentity();
+		}
+	}
+
 	public static enum State {
 		DISABLED,
 		OFFLINE,

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -812,7 +812,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 		final Conversation conversation = message.getConversation();
 		account.deactivateGracePeriod();
 		MessagePacket packet = null;
-		boolean saveInDb = true;
+		final boolean addToConversation = conversation.getMode() != Conversation.MODE_MULTI
+				|| account.getServerIdentity() != XmppConnection.Identity.SLACK;
+		boolean saveInDb = addToConversation;
 		message.setStatus(Message.STATUS_WAITING);
 
 		if (!resend && message.getEncryption() != Message.ENCRYPTION_OTR) {
@@ -924,7 +926,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 		}
 
 		if (resend) {
-			if (packet != null) {
+			if (packet != null && addToConversation) {
 				if (account.getXmppConnection().getFeatures().sm() || conversation.getMode() == Conversation.MODE_MULTI) {
 					markMessage(message, Message.STATUS_UNSEND);
 				} else {
@@ -932,7 +934,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 				}
 			}
 		} else {
-			conversation.add(message);
+			if (addToConversation) {
+				conversation.add(message);
+			}
 			if (saveInDb && (message.getEncryption() == Message.ENCRYPTION_NONE || saveEncryptedMessages())) {
 				databaseBackend.createMessage(message);
 			}

src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java 🔗

@@ -170,6 +170,7 @@ public class XmppConnection implements Runnable {
 			}
 		}
 	};
+	private Identity mServerIdentity = Identity.UNKNOWN;
 
 	private OnIqPacketReceived createPacketReceiveHandler() {
 		return new OnIqPacketReceived() {
@@ -224,6 +225,9 @@ public class XmppConnection implements Runnable {
 		lastConnect = SystemClock.elapsedRealtime();
 		lastPingSent = SystemClock.elapsedRealtime();
 		this.attempt++;
+		if (account.getJid().getDomainpart().equals("chat.facebook.com")) {
+			mServerIdentity = Identity.FACEBOOK;
+		}
 		try {
 			shouldAuthenticate = needsBinding = !account.isOptionSet(Account.OPTION_REGISTER);
 			tagReader = new XmlReader(wakeLock);
@@ -461,7 +465,7 @@ public class XmppConnection implements Runnable {
 							}
 							nextTag = tagReader.readTag();
 						}
-						Log.d(Config.LOGTAG,account.getJid().toBareJid()+": last tag was "+nextTag);
+						Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": last tag was " + nextTag);
 						if (account.getStatus() == Account.State.ONLINE) {
 							account. setStatus(Account.State.OFFLINE);
 							if (statusListener != null) {
@@ -553,7 +557,7 @@ public class XmppConnection implements Runnable {
 					final Pair<IqPacket, OnIqPacketReceived> packetCallbackDuple = packetCallbacks.get(packet.getId());
 					// Packets to the server should have responses from the server
 					if (packetCallbackDuple.first.toServer(account)) {
-						if (packet.fromServer(account) || account.getJid().getDomainpart().equals("chat.facebook.com")) {
+						if (packet.fromServer(account) || mServerIdentity == Identity.FACEBOOK) {
 							callback = packetCallbackDuple.second;
 							packetCallbacks.remove(packet.getId());
 						} else {
@@ -940,8 +944,25 @@ public class XmppConnection implements Runnable {
 							if (element.getName().equals("identity")) {
 								String type = element.getAttribute("type");
 								String category = element.getAttribute("category");
+								String name = element.getAttribute("name");
 								if (type != null && category != null) {
 									info.identities.add(new Pair<>(category, type));
+									if (type.equals("im") && category.equals("server")) {
+										if (name != null && jid.equals(account.getServer())) {
+											switch (name) {
+												case "Prosody":
+													mServerIdentity = Identity.PROSODY;
+													break;
+												case "ejabberd":
+													mServerIdentity = Identity.EJABBERD;
+													break;
+												case "Slack-XMPP":
+													mServerIdentity = Identity.SLACK;
+													break;
+											}
+											Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server name: " + name);
+										}
+									}
 								}
 							} else if (element.getName().equals("feature")) {
 								info.features.add(element.getAttribute("var"));
@@ -1274,6 +1295,10 @@ public class XmppConnection implements Runnable {
 		this.mInteractive = interactive;
 	}
 
+	public Identity getServerIdentity() {
+		return mServerIdentity;
+	}
+
 	private class Info {
 		public final ArrayList<String> features = new ArrayList<>();
 		public final ArrayList<Pair<String,String>> identities = new ArrayList<>();
@@ -1294,6 +1319,13 @@ public class XmppConnection implements Runnable {
 	private class DnsTimeoutException extends IOException {
 
 	}
+	public enum Identity {
+		FACEBOOK,
+		SLACK,
+		EJABBERD,
+		PROSODY,
+		UNKNOWN
+	}
 
 	public class Features {
 		XmppConnection connection;