From 05476102032e921b76db1ad9805b238d0355e94a Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Tue, 15 Jan 2019 21:09:22 +0100 Subject: implement adhoc invite links if server supports this --- .../pixart/messenger/ui/EditAccountActivity.java | 5 ++ .../java/de/pixart/messenger/ui/XmppActivity.java | 12 ++++ .../de/pixart/messenger/xmpp/XmppConnection.java | 73 ++++++++++++++++++++++ .../de/pixart/messenger/xmpp/stanzas/IqPacket.java | 8 +++ src/main/res/layout/activity_edit_account.xml | 22 +++++++ src/main/res/values/strings.xml | 1 + 6 files changed, 121 insertions(+) (limited to 'src') diff --git a/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java b/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java index d04289d22..a20190d17 100644 --- a/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java +++ b/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java @@ -1099,6 +1099,11 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat } else { this.binding.serverInfoSm.setText(R.string.server_info_unavailable); } + if (features.adhocinvite) { + this.binding.serverInfoAdhocInvite.setText(R.string.server_info_available); + } else { + this.binding.serverInfoAdhocInvite.setText(R.string.server_info_unavailable); + } if (features.pep()) { AxolotlService axolotlService = this.mAccount.getAxolotlService(); if (axolotlService != null && axolotlService.isPepBroken()) { diff --git a/src/main/java/de/pixart/messenger/ui/XmppActivity.java b/src/main/java/de/pixart/messenger/ui/XmppActivity.java index 65383c2aa..f0a180353 100644 --- a/src/main/java/de/pixart/messenger/ui/XmppActivity.java +++ b/src/main/java/de/pixart/messenger/ui/XmppActivity.java @@ -88,6 +88,7 @@ import de.pixart.messenger.utils.MenuDoubleTabUtil; import de.pixart.messenger.utils.ThemeHelper; import de.pixart.messenger.xmpp.OnKeyStatusUpdated; import de.pixart.messenger.xmpp.OnUpdateBlocklist; +import de.pixart.messenger.xmpp.XmppConnection; import pl.droidsonroids.gif.GifDrawable; import rocks.xmpp.addr.Jid; @@ -951,6 +952,11 @@ public abstract class XmppActivity extends ActionBarActivity { String user = Jid.of(mAccount.getJid()).getLocal(); String domain = Jid.of(mAccount.getJid()).getDomain(); String inviteURL = Config.inviteUserURL + user + "/" + domain; + XmppConnection.Features features = mAccount.getXmppConnection().getFeatures(); + final boolean adhoclink = features.adhocinvite; + if (adhoclink) { + inviteURL = features.adhocinviteURI; + } String inviteText = getString(R.string.InviteText, user); Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setType("text/plain"); @@ -978,9 +984,15 @@ public abstract class XmppActivity extends ActionBarActivity { builder.setPositiveButton(R.string.ok, (dialog, id) -> { String selection = spinner.getSelectedItem().toString(); + Account mAccount = xmppConnectionService.findAccountByJid(Jid.of(selection).asBareJid()); String user = Jid.of(selection).getLocal(); String domain = Jid.of(selection).getDomain(); String inviteURL = Config.inviteUserURL + user + "/" + domain; + XmppConnection.Features features = mAccount.getXmppConnection().getFeatures(); + final boolean adhoclink = features.adhocinvite; + if (adhoclink) { + inviteURL = features.adhocinviteURI; + } String inviteText = getString(R.string.InviteText, user); Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java index f364a0155..5e3205684 100644 --- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java +++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java @@ -1297,6 +1297,7 @@ public class XmppConnection implements Runnable { for (Jid jid : items) { sendServiceDiscoveryInfo(jid); } + getInviteAdHoc(server); } else { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": could not query disco items of " + server); } @@ -1309,6 +1310,76 @@ public class XmppConnection implements Runnable { }); } + private void getInviteAdHoc(final Jid server) { + mPendingServiceDiscoveries.incrementAndGet(); + ArrayList nodes = new ArrayList(); + IqPacket iq = new IqPacket(IqPacket.TYPE.GET); + iq.setTo(Jid.ofDomain(server.getDomain())); + iq.setFrom(Jid.of(account.getJid().asBareJid())); + iq.setAttribute("query", "jabber:client"); + final Element query = iq.addChild("query", "http://jabber.org/protocol/disco#items"); + query.setAttribute("node", "http://jabber.org/protocol/commands"); + this.sendIqPacket(iq, (account, packet) -> { + if (packet.getType() == IqPacket.TYPE.RESULT) { + final List elements = packet.query().getChildren(); + for (final Element element : elements) { + if (element.getName().equals("item")) { + final Jid jid = InvalidJid.getNullForInvalid(element.getAttributeAsJid("jid")); + if (jid != null && jid.equals(Jid.of(account.getServer()))) { + final String node = element.getAttribute("node"); + if (node.equals("invite")) { + features.adhocinvite = true; + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": query disco commands of " + server + " was successful"); + getAdHocInviteUrl(server); + } + nodes.add(node); + } + } + } + } else { + features.adhocinvite = false; + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": could not query disco commands of " + server); + } + if (packet.getType() != IqPacket.TYPE.TIMEOUT) { + if (mPendingServiceDiscoveries.decrementAndGet() == 0 + && mWaitForDisco.compareAndSet(true, false)) { + finalizeBind(); + } + } + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": query disco commands of " + server + " was " + features.adhocinvite); + }); + } + + private void getAdHocInviteUrl(final Jid server) { + IqPacket iqPacket = new IqPacket(IqPacket.TYPE.SET); + iqPacket.setTo(Jid.ofDomain(server.getDomain())); + iqPacket.setFrom(Jid.of(account.getJid().asBareJid())); + iqPacket.setContent("jabber:client"); + final Element command = iqPacket.addChild("command", "http://jabber.org/protocol/commands"); + command.setAttribute("node", "invite"); + command.setAttribute("action", "execute"); + Log.d(Config.LOGTAG, "AdHoc URL command " + iqPacket); + this.sendIqPacket(iqPacket, (account, packet) -> { + Log.d(Config.LOGTAG, "AdHoc URL packet " + packet); + if (packet.getType() == IqPacket.TYPE.RESULT) { + final List elements = packet.command().getChildren(); + for (final Element element : elements) { + features.adhocinviteURI = element.getContent(); + Log.d(Config.LOGTAG, "Commands URI: " + features.adhocinviteURI); + } + } else { + features.adhocinviteURI = ""; + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": could not query disco commands of " + server); + } + if (packet.getType() != IqPacket.TYPE.TIMEOUT) { + if (mPendingServiceDiscoveries.decrementAndGet() == 0 + && mWaitForDisco.compareAndSet(true, false)) { + finalizeBind(); + } + } + }); + } + private void sendEnableCarbons() { final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.addChild("enable", "urn:xmpp:carbons:2"); @@ -1756,6 +1827,8 @@ public class XmppConnection implements Runnable { } public class Features { + public boolean adhocinvite; + public String adhocinviteURI; XmppConnection connection; private boolean carbonsEnabled = false; private boolean encryptionEnabled = false; diff --git a/src/main/java/de/pixart/messenger/xmpp/stanzas/IqPacket.java b/src/main/java/de/pixart/messenger/xmpp/stanzas/IqPacket.java index 5f4e39eca..c74ec3237 100644 --- a/src/main/java/de/pixart/messenger/xmpp/stanzas/IqPacket.java +++ b/src/main/java/de/pixart/messenger/xmpp/stanzas/IqPacket.java @@ -32,6 +32,14 @@ public class IqPacket extends AbstractAcknowledgeableStanza { return query; } + public Element command() { + Element command = findChild("command"); + if (command == null) { + command = addChild("command"); + } + return command; + } + public Element query(final String xmlns) { final Element query = query(); query.setAttribute("xmlns", xmlns); diff --git a/src/main/res/layout/activity_edit_account.xml b/src/main/res/layout/activity_edit_account.xml index 30ae5b192..6aced7fd3 100644 --- a/src/main/res/layout/activity_edit_account.xml +++ b/src/main/res/layout/activity_edit_account.xml @@ -519,6 +519,28 @@ android:textAppearance="@style/TextAppearance.Conversations.Body1" /> + + + + + + + Automatically join this group chat Play GIF files in chat Setting this to true plays GIF files directly inside the chat view. + XEP-0050: Ad-Hoc Commands: user invite -- cgit v1.2.3