support for XEP-0092: Software Version

iNPUTmice created

Change summary

src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java | 22 
src/main/java/eu/siacs/conversations/generator/IqGenerator.java       | 13 
src/main/java/eu/siacs/conversations/parser/IqParser.java             |  8 
src/main/java/eu/siacs/conversations/ui/AboutPreference.java          | 14 
src/main/java/eu/siacs/conversations/utils/PhoneHelper.java           | 14 
5 files changed, 51 insertions(+), 20 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java 🔗

@@ -13,6 +13,7 @@ import java.util.Locale;
 import java.util.TimeZone;
 
 import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.utils.PhoneHelper;
 
 public abstract class AbstractGenerator {
 	private final String[] FEATURES = {
@@ -25,12 +26,14 @@ public abstract class AbstractGenerator {
 			"http://jabber.org/protocol/caps",
 			"http://jabber.org/protocol/disco#info",
 			"urn:xmpp:avatar:metadata+notify",
-			"urn:xmpp:ping"};
+			"urn:xmpp:ping",
+			"jabber:iq:version"};
 	private final String[] MESSAGE_CONFIRMATION_FEATURES = {
 			"urn:xmpp:chat-markers:0",
 			"urn:xmpp:receipts"
 	};
-	public final String IDENTITY_NAME = "Conversations 1.0";
+	private String mVersion = null;
+	public final String IDENTITY_NAME = "Conversations";
 	public final String IDENTITY_TYPE = "phone";
 
 	private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
@@ -41,10 +44,21 @@ public abstract class AbstractGenerator {
 		this.mXmppConnectionService = service;
 	}
 
+	protected String getIdentityVersion() {
+		if (mVersion == null) {
+			this.mVersion = PhoneHelper.getVersionName(mXmppConnectionService);
+		}
+		return this.mVersion;
+	}
+
+	protected String getIdentityName() {
+		return IDENTITY_NAME + " " + getIdentityVersion();
+	}
+
 	public String getCapHash() {
 		StringBuilder s = new StringBuilder();
-		s.append("client/" + IDENTITY_TYPE + "//" + IDENTITY_NAME + "<");
-		MessageDigest md = null;
+		s.append("client/" + IDENTITY_TYPE + "//" + getIdentityName() + "<");
+		MessageDigest md;
 		try {
 			md = MessageDigest.getInstance("SHA-1");
 		} catch (NoSuchAlgorithmException e) {

src/main/java/eu/siacs/conversations/generator/IqGenerator.java 🔗

@@ -8,6 +8,7 @@ import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.services.MessageArchiveService;
 import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.utils.PhoneHelper;
 import eu.siacs.conversations.utils.Xmlns;
 import eu.siacs.conversations.xml.Element;
 import eu.siacs.conversations.xmpp.forms.Data;
@@ -30,14 +31,22 @@ public class IqGenerator extends AbstractGenerator {
 		query.setAttribute("node", request.query().getAttribute("node"));
 		final Element identity = query.addChild("identity");
 		identity.setAttribute("category", "client");
-		identity.setAttribute("type", this.IDENTITY_TYPE);
-		identity.setAttribute("name", IDENTITY_NAME);
+		identity.setAttribute("type", IDENTITY_TYPE);
+		identity.setAttribute("name", getIdentityName());
 		for (final String feature : getFeatures()) {
 			query.addChild("feature").setAttribute("var", feature);
 		}
 		return packet;
 	}
 
+	public IqPacket versionResponse(final IqPacket request) {
+		final IqPacket packet = request.generateResponse(IqPacket.TYPE.RESULT);
+		Element query = packet.query("jabber:iq:version");
+		query.addChild("name").setContent(IDENTITY_NAME);
+		query.addChild("version").setContent(getIdentityVersion());
+		return packet;
+	}
+
 	protected IqPacket publish(final String node, final Element item) {
 		final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
 		final Element pubsub = packet.addChild("pubsub",

src/main/java/eu/siacs/conversations/parser/IqParser.java 🔗

@@ -134,9 +134,11 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
 			mXmppConnectionService.getJingleConnectionManager()
 				.deliverIbbPacket(account, packet);
 		} else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
-			final IqPacket response = mXmppConnectionService.getIqGenerator()
-				.discoResponse(packet);
-			account.getXmppConnection().sendIqPacket(response, null);
+			final IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(packet);
+			mXmppConnectionService.sendIqPacket(account, response, null);
+		} else if (packet.hasChild("query","jabber:iq:version")) {
+			final IqPacket response = mXmppConnectionService.getIqGenerator().versionResponse(packet);
+			mXmppConnectionService.sendIqPacket(account,response,null);
 		} else if (packet.hasChild("ping", "urn:xmpp:ping")) {
 			final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
 			mXmppConnectionService.sendIqPacket(account, response, null);

src/main/java/eu/siacs/conversations/ui/AboutPreference.java 🔗

@@ -6,6 +6,8 @@ import android.content.pm.PackageManager;
 import android.preference.Preference;
 import android.util.AttributeSet;
 
+import eu.siacs.conversations.utils.PhoneHelper;
+
 public class AboutPreference extends Preference {
 	public AboutPreference(final Context context, final AttributeSet attrs, final int defStyle) {
 		super(context, attrs, defStyle);
@@ -25,17 +27,7 @@ public class AboutPreference extends Preference {
     }
 
     private void setSummary() {
-		if (getContext() != null && getContext().getPackageManager() != null) {
-			final String packageName = getContext().getPackageName();
-			final String versionName;
-			try {
-				versionName = getContext().getPackageManager().getPackageInfo(packageName, 0).versionName;
-				setSummary("Conversations " + versionName);
-			} catch (final PackageManager.NameNotFoundException e) {
-				// Using try/catch as part of the logic is sort of like this:
-				// https://xkcd.com/292/
-			}
-		}
+		setSummary("Conversations " + PhoneHelper.getVersionName(getContext()));
 	}
 }
 

src/main/java/eu/siacs/conversations/utils/PhoneHelper.java 🔗

@@ -8,6 +8,7 @@ import android.content.Context;
 import android.content.CursorLoader;
 import android.content.Loader;
 import android.content.Loader.OnLoadCompleteListener;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
@@ -91,4 +92,17 @@ public class PhoneHelper {
 			}
 		}
 	}
+
+	public static String getVersionName(Context context) {
+		final String packageName = context == null ? null : context.getPackageName();
+		if (packageName != null) {
+			try {
+				return context.getPackageManager().getPackageInfo(packageName, 0).versionName;
+			} catch (final PackageManager.NameNotFoundException e) {
+				return "unknown";
+			}
+		} else {
+			return "unknown";
+		}
+	}
 }