aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
diff options
context:
space:
mode:
authorSam Whited <sam@samwhited.com>2014-12-21 15:43:58 -0500
committerSam Whited <sam@samwhited.com>2014-12-22 08:19:00 -0500
commitaf7a64491fa5c514866d0f1952c034a7672bb508 (patch)
tree38e73cc693fef7462ecabffd984348a86b768ae3 /src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
parent96569700512e9618efa18eeb277665045678e16d (diff)
Add support for XEP-0191 (Blocking command)
Fixes #791 Squash of commits: 534f25d7dae3ce6852243e28fdd0a69ac01e9463 808fdf5147f27a912a60bee39aa4bf1ddd4f43b4 1eaf8a8330710ad35ba7c368e04f909af623ae4c 31585242c2359efdcd0eeddb9745077f54dbc9eb 2e69bd0bd0286ed1e98a42f4c3421ba4d8cf524b e904fb5015bf3a1904ab941a1957edf3b1e7abd2 eebbadf3b3816bbf8fcccb763e419fed252d266f 7c5b87724ce494e5a6e8026557ed50a8fd9f23e8 b0eaaf446937794fe19cbdb4f8309c3ff83d4e42 8c652f9e8bb3512958d9ad8c6f1326505f2d98c8 ad0ea1ad948ff6f8fde7b0b10f5163dc8852032f f5d49897e0dba691ef53a0eddb9ed34d129ad442 a08fa64c505bd895b7c626cfad182380373be20b de67079113e08394a276048c31f6b21baa300829 9069f342173ba30c2b20c67529c7ff497a6a257d 0169fa79d161ee898c4b6762e207087682a952d8 8585a5bd75a5d56927fed8317729bd15fffe4dcc 0053528a078369e0b65dcf71bda251072a1299c7 e901a9c3554bd7cca193e92919b463991eadfea7 c5c78257434813c69ab9b7558bcc8f7cbe858433 e905af348d46d77bc46b5f7211527684acc02fab 13a0f9a10c7892b0f90f5fabd2f2615701b0fd66 2cfba1e24b0139839e4453b92be7e20634d150cf 58e074fb5bb44b05a8104250fccd7c024c808c1a 0d6cf98fc8eab212d798ac79b336f9b70a14f06d e23620f56b85bcab9f3b5d9ce1c01524cd9674dc d72cd2fcc8d54176c3ff53411a69b9bb4642eff3 195143dff8836623a37094a6b8fa6aa01ef31580 5f5f3caf3a1e480a99d27ee5c34ba516419c52e4 1dee3d5861c9f9c710da4cbda3688d94c622ca93 23949b8aa32c78b27bab49bb3c4f3ff588925ce1 9bf97f8ae522796e0dacb7f6fe7a7f90f86a93a1
Diffstat (limited to 'src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java')
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java256
1 files changed, 131 insertions, 125 deletions
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index b090d651..7fd0a4b6 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -30,10 +30,12 @@ import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import javax.net.ssl.HostnameVerifier;
@@ -48,8 +50,10 @@ import eu.siacs.conversations.crypto.sasl.Plain;
import eu.siacs.conversations.crypto.sasl.SaslMechanism;
import eu.siacs.conversations.crypto.sasl.ScramSha1;
import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.generator.IqGenerator;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.DNSHelper;
+import eu.siacs.conversations.utils.Xmlns;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.Tag;
import eu.siacs.conversations.xml.TagWriter;
@@ -76,19 +80,19 @@ public class XmppConnection implements Runnable {
private static final int PACKET_PRESENCE = 2;
private final Context applicationContext;
protected Account account;
- private WakeLock wakeLock;
+ private final WakeLock wakeLock;
private Socket socket;
private XmlReader tagReader;
private TagWriter tagWriter;
- private Features features = new Features(this);
+ private final Features features = new Features(this);
private boolean shouldBind = true;
private boolean shouldAuthenticate = true;
private Element streamFeatures;
- private HashMap<String, List<String>> disco = new HashMap<>();
+ private final HashMap<String, List<String>> disco = new HashMap<>();
private String streamId = null;
private int smVersion = 3;
- private SparseArray<String> messageReceipts = new SparseArray<>();
+ private final SparseArray<String> messageReceipts = new SparseArray<>();
private boolean enabledEncryption = false;
private boolean enabledCarbons = false;
@@ -100,20 +104,20 @@ public class XmppConnection implements Runnable {
private long lastConnect = 0;
private long lastSessionStarted = 0;
private int attempt = 0;
- private Hashtable<String, PacketReceived> packetCallbacks = new Hashtable<>();
+ private final Map<String, PacketReceived> packetCallbacks = new Hashtable<>();
private OnPresencePacketReceived presenceListener = null;
private OnJinglePacketReceived jingleListener = null;
private OnIqPacketReceived unregisteredIqListener = null;
private OnMessagePacketReceived messageListener = null;
private OnStatusChanged statusListener = null;
private OnBindListener bindListener = null;
- private ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
+ private final ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
private OnMessageAcknowledged acknowledgedListener = null;
private XmppConnectionService mXmppConnectionService = null;
private SaslMechanism saslMechanism;
- public XmppConnection(Account account, XmppConnectionService service) {
+ public XmppConnection(final Account account, final XmppConnectionService service) {
this.account = account;
this.wakeLock = service.getPowerManager().newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, account.getJid().toBareJid().toString());
@@ -129,7 +133,7 @@ public class XmppConnection implements Runnable {
&& (account.getStatus() != Account.State.ONLINE)
&& (account.getStatus() != Account.State.DISABLED)) {
return;
- }
+ }
if (nextStatus == Account.State.ONLINE) {
this.attempt = 0;
}
@@ -153,15 +157,15 @@ public class XmppConnection implements Runnable {
tagWriter = new TagWriter();
packetCallbacks.clear();
this.changeStatus(Account.State.CONNECTING);
- Bundle result = DNSHelper.getSRVRecord(account.getServer());
- ArrayList<Parcelable> values = result.getParcelableArrayList("values");
+ final Bundle result = DNSHelper.getSRVRecord(account.getServer());
+ final ArrayList<Parcelable> values = result.getParcelableArrayList("values");
if ("timeout".equals(result.getString("error"))) {
throw new IOException("timeout in dns");
} else if (values != null) {
int i = 0;
boolean socketError = true;
while (socketError && values.size() > i) {
- Bundle namePort = (Bundle) values.get(i);
+ final Bundle namePort = (Bundle) values.get(i);
try {
String srvRecordServer;
try {
@@ -170,9 +174,9 @@ public class XmppConnection implements Runnable {
// TODO: Handle me?`
srvRecordServer = "";
}
- int srvRecordPort = namePort.getInt("port");
- String srvIpServer = namePort.getString("ip");
- InetSocketAddress addr;
+ final int srvRecordPort = namePort.getInt("port");
+ final String srvIpServer = namePort.getString("ip");
+ final InetSocketAddress addr;
if (srvIpServer != null) {
addr = new InetSocketAddress(srvIpServer, srvRecordPort);
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
@@ -187,10 +191,10 @@ public class XmppConnection implements Runnable {
socket = new Socket();
socket.connect(addr, 20000);
socketError = false;
- } catch (UnknownHostException e) {
+ } catch (final UnknownHostException e) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
i++;
- } catch (IOException e) {
+ } catch (final IOException e) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
i++;
}
@@ -204,9 +208,9 @@ public class XmppConnection implements Runnable {
} else {
throw new IOException("timeout in dns");
}
- OutputStream out = socket.getOutputStream();
+ final OutputStream out = socket.getOutputStream();
tagWriter.setOutputStream(out);
- InputStream in = socket.getInputStream();
+ final InputStream in = socket.getInputStream();
tagReader.setInputStream(in);
tagWriter.beginDocument();
sendStartStream();
@@ -222,14 +226,9 @@ public class XmppConnection implements Runnable {
if (socket.isConnected()) {
socket.close();
}
- } catch (UnknownHostException e) {
- this.changeStatus(Account.State.SERVER_NOT_FOUND);
- } catch (final ConnectException e) {
+ } catch (final UnknownHostException | ConnectException e) {
this.changeStatus(Account.State.SERVER_NOT_FOUND);
- } catch (final IOException | XmlPullParserException e) {
- Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
- this.changeStatus(Account.State.OFFLINE);
- } catch (NoSuchAlgorithmException e) {
+ } catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
this.changeStatus(Account.State.OFFLINE);
} finally {
@@ -268,7 +267,7 @@ public class XmppConnection implements Runnable {
}
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in");
account.setKey(Account.PINNED_MECHANISM_KEY,
- String.valueOf(saslMechanism.getPriority()));
+ String.valueOf(saslMechanism.getPriority()));
tagReader.reset();
sendStartStream();
processStream(tagReader.readTag());
@@ -289,7 +288,7 @@ public class XmppConnection implements Runnable {
}
tagWriter.writeElement(response);
} else if (nextTag.isStart("enabled")) {
- Element enabled = tagReader.readElement(nextTag);
+ final Element enabled = tagReader.readElement(nextTag);
if ("true".equals(enabled.getAttribute("resume"))) {
this.streamId = enabled.getAttribute("id");
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
@@ -301,14 +300,14 @@ public class XmppConnection implements Runnable {
}
this.lastSessionStarted = SystemClock.elapsedRealtime();
this.stanzasReceived = 0;
- RequestPacket r = new RequestPacket(smVersion);
+ final RequestPacket r = new RequestPacket(smVersion);
tagWriter.writeStanzaAsync(r);
} else if (nextTag.isStart("resumed")) {
lastPaketReceived = SystemClock.elapsedRealtime();
- Element resumed = tagReader.readElement(nextTag);
- String h = resumed.getAttribute("h");
+ final Element resumed = tagReader.readElement(nextTag);
+ final String h = resumed.getAttribute("h");
try {
- int serverCount = Integer.parseInt(h);
+ final int serverCount = Integer.parseInt(h);
if (serverCount != stanzasSent) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+ ": session resumed with lost packages");
@@ -327,20 +326,19 @@ public class XmppConnection implements Runnable {
}
messageReceipts.clear();
} catch (final NumberFormatException ignored) {
-
}
sendServiceDiscoveryInfo(account.getServer());
sendServiceDiscoveryItems(account.getServer());
sendInitialPing();
} else if (nextTag.isStart("r")) {
tagReader.readElement(nextTag);
- AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
+ final AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
tagWriter.writeStanzaAsync(ack);
} else if (nextTag.isStart("a")) {
- Element ack = tagReader.readElement(nextTag);
+ final Element ack = tagReader.readElement(nextTag);
lastPaketReceived = SystemClock.elapsedRealtime();
- int serverSequence = Integer.parseInt(ack.getAttribute("h"));
- String msgId = this.messageReceipts.get(serverSequence);
+ final int serverSequence = Integer.parseInt(ack.getAttribute("h"));
+ final String msgId = this.messageReceipts.get(serverSequence);
if (msgId != null) {
if (this.acknowledgedListener != null) {
this.acknowledgedListener.onMessageAcknowledged(
@@ -374,13 +372,12 @@ public class XmppConnection implements Runnable {
private void sendInitialPing() {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": sending intial ping");
- IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
+ final IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
iq.setFrom(account.getJid());
iq.addChild("ping", "urn:xmpp:ping");
this.sendIqPacket(iq, new OnIqPacketReceived() {
-
@Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
+ public void onIqPacketReceived(final Account account, final IqPacket packet) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+ ": online with resource " + account.getResource());
changeStatus(Account.State.ONLINE);
@@ -388,7 +385,7 @@ public class XmppConnection implements Runnable {
});
}
- private Element processPacket(Tag currentTag, int packetType)
+ private Element processPacket(final Tag currentTag, final int packetType)
throws XmlPullParserException, IOException {
Element element;
switch (packetType) {
@@ -411,8 +408,8 @@ public class XmppConnection implements Runnable {
}
while (!nextTag.isEnd(element.getName())) {
if (!nextTag.isNo()) {
- Element child = tagReader.readElement(nextTag);
- String type = currentTag.getAttribute("type");
+ final Element child = tagReader.readElement(nextTag);
+ final String type = currentTag.getAttribute("type");
if (packetType == PACKET_IQ
&& "jingle".equals(child.getName())
&& ("set".equalsIgnoreCase(type) || "get"
@@ -432,9 +429,9 @@ public class XmppConnection implements Runnable {
return element;
}
- private void processIq(Tag currentTag) throws XmlPullParserException,
+ private void processIq(final Tag currentTag) throws XmlPullParserException,
IOException {
- IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ);
+ final IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ);
if (packet.getId() == null) {
return; // an iq packet without id is definitely invalid
@@ -461,11 +458,11 @@ public class XmppConnection implements Runnable {
}
}
- private void processMessage(Tag currentTag) throws XmlPullParserException,
+ private void processMessage(final Tag currentTag) throws XmlPullParserException,
IOException {
- MessagePacket packet = (MessagePacket) processPacket(currentTag,
+ final MessagePacket packet = (MessagePacket) processPacket(currentTag,
PACKET_MESSAGE);
- String id = packet.getAttribute("id");
+ final String id = packet.getAttribute("id");
if ((id != null) && (packetCallbacks.containsKey(id))) {
if (packetCallbacks.get(id) instanceof OnMessagePacketReceived) {
((OnMessagePacketReceived) packetCallbacks.get(id))
@@ -477,11 +474,11 @@ public class XmppConnection implements Runnable {
}
}
- private void processPresence(Tag currentTag) throws XmlPullParserException,
+ private void processPresence(final Tag currentTag) throws XmlPullParserException,
IOException {
PresencePacket packet = (PresencePacket) processPacket(currentTag,
PACKET_PRESENCE);
- String id = packet.getAttribute("id");
+ final String id = packet.getAttribute("id");
if ((id != null) && (packetCallbacks.containsKey(id))) {
if (packetCallbacks.get(id) instanceof OnPresencePacketReceived) {
((OnPresencePacketReceived) packetCallbacks.get(id))
@@ -494,7 +491,7 @@ public class XmppConnection implements Runnable {
}
private void sendStartTLS() throws IOException {
- Tag startTLS = Tag.empty("starttls");
+ final Tag startTLS = Tag.empty("starttls");
startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls");
tagWriter.writeTag(startTLS);
}
@@ -512,11 +509,11 @@ public class XmppConnection implements Runnable {
IOException {
tagReader.readTag();
try {
- SSLContext sc = SSLContext.getInstance("TLS");
+ final SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null,
new X509TrustManager[]{this.mXmppConnectionService.getMemorizingTrustManager()},
mXmppConnectionService.getRNG());
- SSLSocketFactory factory = sc.getSocketFactory();
+ final SSLSocketFactory factory = sc.getSocketFactory();
if (factory == null) {
throw new IOException("SSLSocketFactory was null");
@@ -541,7 +538,7 @@ public class XmppConnection implements Runnable {
if (enableLegacySSL()) {
supportProtocols = sslSocket.getSupportedProtocols();
} else {
- final List<String> supportedProtocols = new LinkedList<>(
+ final Collection<String> supportedProtocols = new LinkedList<>(
Arrays.asList(sslSocket.getSupportedProtocols()));
supportedProtocols.remove("SSLv3");
supportProtocols = new String[supportedProtocols.size()];
@@ -549,13 +546,13 @@ public class XmppConnection implements Runnable {
}
sslSocket.setEnabledProtocols(supportProtocols);
- if (verifier != null
- && !verifier.verify(account.getServer().getDomainpart(),
- sslSocket.getSession())) {
+ if (verifier != null
+ && !verifier.verify(account.getServer().getDomainpart(),
+ sslSocket.getSession())) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed");
disconnect(true);
changeStatus(Account.State.SECURITY_ERROR);
- }
+ }
tagReader.setInputStream(sslSocket.getInputStream());
tagWriter.setOutputStream(sslSocket.getOutputStream());
sendStartStream();
@@ -569,7 +566,7 @@ public class XmppConnection implements Runnable {
}
}
- private void processStreamFeatures(Tag currentTag)
+ private void processStreamFeatures(final Tag currentTag)
throws XmlPullParserException, IOException {
this.streamFeatures = tagReader.readElement(currentTag);
if (this.streamFeatures.hasChild("starttls") && !enabledEncryption) {
@@ -605,7 +602,7 @@ public class XmppConnection implements Runnable {
"). Possible downgrade attack?");
disconnect(true);
changeStatus(Account.State.SECURITY_ERROR);
- }
+ }
} catch (final JSONException e) {
Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism");
}
@@ -618,7 +615,7 @@ public class XmppConnection implements Runnable {
} else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:"
+ smVersion)
&& streamId != null) {
- ResumePacket resume = new ResumePacket(this.streamId,
+ final ResumePacket resume = new ResumePacket(this.streamId,
stanzasReceived, smVersion);
this.tagWriter.writeStanzaAsync(resume);
} else if (this.streamFeatures.hasChild("bind") && shouldBind) {
@@ -629,45 +626,44 @@ public class XmppConnection implements Runnable {
}
}
- private List<String> extractMechanisms(Element stream) {
- ArrayList<String> mechanisms = new ArrayList<>(stream
+ private List<String> extractMechanisms(final Element stream) {
+ final ArrayList<String> mechanisms = new ArrayList<>(stream
.getChildren().size());
- for (Element child : stream.getChildren()) {
+ for (final Element child : stream.getChildren()) {
mechanisms.add(child.getContent());
}
return mechanisms;
}
private void sendRegistryRequest() {
- IqPacket register = new IqPacket(IqPacket.TYPE_GET);
+ final IqPacket register = new IqPacket(IqPacket.TYPE_GET);
register.query("jabber:iq:register");
register.setTo(account.getServer());
sendIqPacket(register, new OnIqPacketReceived() {
@Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- Element instructions = packet.query().findChild("instructions");
+ public void onIqPacketReceived(final Account account, final IqPacket packet) {
+ final Element instructions = packet.query().findChild("instructions");
if (packet.query().hasChild("username")
&& (packet.query().hasChild("password"))) {
- IqPacket register = new IqPacket(IqPacket.TYPE_SET);
- Element username = new Element("username")
- .setContent(account.getUsername());
- Element password = new Element("password")
- .setContent(account.getPassword());
+ final IqPacket register = new IqPacket(IqPacket.TYPE_SET);
+ final Element username = new Element("username")
+ .setContent(account.getUsername());
+ final Element password = new Element("password")
+ .setContent(account.getPassword());
register.query("jabber:iq:register").addChild(username);
register.query().addChild(password);
sendIqPacket(register, new OnIqPacketReceived() {
@Override
- public void onIqPacketReceived(Account account,
- IqPacket packet) {
+ public void onIqPacketReceived(final Account account, final IqPacket packet) {
if (packet.getType() == IqPacket.TYPE_RESULT) {
account.setOption(Account.OPTION_REGISTER,
false);
changeStatus(Account.State.REGISTRATION_SUCCESSFUL);
} else if (packet.hasChild("error")
&& (packet.findChild("error")
- .hasChild("conflict"))) {
+ .hasChild("conflict"))) {
changeStatus(Account.State.REGISTRATION_CONFLICT);
} else {
changeStatus(Account.State.REGISTRATION_FAILED);
@@ -687,14 +683,14 @@ public class XmppConnection implements Runnable {
});
}
- private void sendBindRequest() throws IOException {
- IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
+ private void sendBindRequest() {
+ final IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind")
.addChild("resource").setContent(account.getResource());
this.sendUnboundIqPacket(iq, new OnIqPacketReceived() {
@Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- Element bind = packet.findChild("bind");
+ public void onIqPacketReceived(final Account account, final IqPacket packet) {
+ final Element bind = packet.findChild("bind");
if (bind != null) {
final Element jid = bind.findChild("jid");
if (jid != null && jid.getContent() != null) {
@@ -705,14 +701,14 @@ public class XmppConnection implements Runnable {
}
if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) {
smVersion = 3;
- EnablePacket enable = new EnablePacket(smVersion);
+ final EnablePacket enable = new EnablePacket(smVersion);
tagWriter.writeStanzaAsync(enable);
stanzasSent = 0;
messageReceipts.clear();
} else if (streamFeatures.hasChild("sm",
- "urn:xmpp:sm:2")) {
+ "urn:xmpp:sm:2")) {
smVersion = 2;
- EnablePacket enable = new EnablePacket(smVersion);
+ final EnablePacket enable = new EnablePacket(smVersion);
tagWriter.writeStanzaAsync(enable);
stanzasSent = 0;
messageReceipts.clear();
@@ -736,7 +732,7 @@ public class XmppConnection implements Runnable {
if (this.streamFeatures.hasChild("session")) {
Log.d(Config.LOGTAG, account.getJid().toBareJid()
+ ": sending deprecated session");
- IqPacket startSession = new IqPacket(IqPacket.TYPE_SET);
+ final IqPacket startSession = new IqPacket(IqPacket.TYPE_SET);
startSession.addChild("session",
"urn:ietf:params:xml:ns:xmpp-session");
this.sendUnboundIqPacket(startSession, null);
@@ -755,10 +751,10 @@ public class XmppConnection implements Runnable {
this.sendIqPacket(iq, new OnIqPacketReceived() {
@Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
+ public void onIqPacketReceived(final Account account, final IqPacket packet) {
final List<Element> elements = packet.query().getChildren();
final List<String> features = new ArrayList<>();
- for (Element element : elements) {
+ for (final Element element : elements) {
if (element.getName().equals("identity")) {
if ("irc".equals(element.getAttribute("type"))) {
//add fake feature to not confuse irc and real muc
@@ -772,7 +768,7 @@ public class XmppConnection implements Runnable {
if (account.getServer().equals(server.toDomainJid())) {
enableAdvancedStreamFeatures();
- for(OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) {
+ for (final OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) {
listener.onAdvancedStreamFeaturesAvailable(account);
}
}
@@ -787,6 +783,10 @@ public class XmppConnection implements Runnable {
sendEnableCarbons();
}
}
+ if (getFeatures().blocking()) {
+ Log.d(Config.LOGTAG, "Requesting block list");
+ this.sendIqPacket(getIqGenerator().generateGetBlockList(), mXmppConnectionService.getIqParser());
+ }
}
private void sendServiceDiscoveryItems(final Jid server) {
@@ -796,9 +796,9 @@ public class XmppConnection implements Runnable {
this.sendIqPacket(iq, new OnIqPacketReceived() {
@Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- List<Element> elements = packet.query().getChildren();
- for (Element element : elements) {
+ public void onIqPacketReceived(final Account account, final IqPacket packet) {
+ final List<Element> elements = packet.query().getChildren();
+ for (final Element element : elements) {
if (element.getName().equals("item")) {
final Jid jid = element.getAttributeAsJid("jid");
if (jid != null && !jid.equals(account.getServer())) {
@@ -811,12 +811,12 @@ public class XmppConnection implements Runnable {
}
private void sendEnableCarbons() {
- IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
+ final IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
iq.addChild("enable", "urn:xmpp:carbons:2");
this.sendIqPacket(iq, new OnIqPacketReceived() {
@Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
+ public void onIqPacketReceived(final Account account, final IqPacket packet) {
if (!packet.hasChild("error")) {
Log.d(Config.LOGTAG, account.getJid().toBareJid()
+ ": successfully enabled carbons");
@@ -829,20 +829,20 @@ public class XmppConnection implements Runnable {
});
}
- private void processStreamError(Tag currentTag)
+ private void processStreamError(final Tag currentTag)
throws XmlPullParserException, IOException {
- Element streamError = tagReader.readElement(currentTag);
+ final Element streamError = tagReader.readElement(currentTag);
if (streamError != null && streamError.hasChild("conflict")) {
final String resource = account.getResource().split("\\.")[0];
account.setResource(resource + "." + nextRandomId());
Log.d(Config.LOGTAG,
account.getJid().toBareJid() + ": switching resource due to conflict ("
- + account.getResource() + ")");
+ + account.getResource() + ")");
}
}
private void sendStartStream() throws IOException {
- Tag stream = Tag.start("stream:stream");
+ final Tag stream = Tag.start("stream:stream");
stream.setAttribute("from", account.getJid().toBareJid().toString());
stream.setAttribute("to", account.getServer().toString());
stream.setAttribute("version", "1.0");
@@ -856,33 +856,32 @@ public class XmppConnection implements Runnable {
return new BigInteger(50, mXmppConnectionService.getRNG()).toString(32);
}
- public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) {
+ public void sendIqPacket(final IqPacket packet, final PacketReceived callback) {
if (packet.getId() == null) {
- String id = nextRandomId();
+ final String id = nextRandomId();
packet.setAttribute("id", id);
}
packet.setFrom(account.getJid());
this.sendPacket(packet, callback);
}
- public void sendUnboundIqPacket(IqPacket packet, OnIqPacketReceived callback) {
+ public void sendUnboundIqPacket(final IqPacket packet, final PacketReceived callback) {
if (packet.getId() == null) {
- String id = nextRandomId();
+ final String id = nextRandomId();
packet.setAttribute("id", id);
}
this.sendPacket(packet, callback);
}
- public void sendMessagePacket(MessagePacket packet) {
+ public void sendMessagePacket(final MessagePacket packet) {
this.sendPacket(packet, null);
}
- public void sendPresencePacket(PresencePacket packet) {
+ public void sendPresencePacket(final PresencePacket packet) {
this.sendPacket(packet, null);
}
- private synchronized void sendPacket(final AbstractStanza packet,
- PacketReceived callback) {
+ private synchronized void sendPacket(final AbstractStanza packet, final PacketReceived callback) {
if (packet.getName().equals("iq") || packet.getName().equals("message")
|| packet.getName().equals("presence")) {
++stanzasSent;
@@ -907,7 +906,7 @@ public class XmppConnection implements Runnable {
if (streamFeatures.hasChild("sm")) {
tagWriter.writeStanzaAsync(new RequestPacket(smVersion));
} else {
- IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
+ final IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
iq.setFrom(account.getJid());
iq.addChild("ping", "urn:xmpp:ping");
this.sendIqPacket(iq, null);
@@ -916,44 +915,44 @@ public class XmppConnection implements Runnable {
}
public void setOnMessagePacketReceivedListener(
- OnMessagePacketReceived listener) {
+ final OnMessagePacketReceived listener) {
this.messageListener = listener;
}
public void setOnUnregisteredIqPacketReceivedListener(
- OnIqPacketReceived listener) {
+ final OnIqPacketReceived listener) {
this.unregisteredIqListener = listener;
}
public void setOnPresencePacketReceivedListener(
- OnPresencePacketReceived listener) {
+ final OnPresencePacketReceived listener) {
this.presenceListener = listener;
}
public void setOnJinglePacketReceivedListener(
- OnJinglePacketReceived listener) {
+ final OnJinglePacketReceived listener) {
this.jingleListener = listener;
}
- public void setOnStatusChangedListener(OnStatusChanged listener) {
+ public void setOnStatusChangedListener(final OnStatusChanged listener) {
this.statusListener = listener;
}
- public void setOnBindListener(OnBindListener listener) {
+ public void setOnBindListener(final OnBindListener listener) {
this.bindListener = listener;
}
- public void setOnMessageAcknowledgeListener(OnMessageAcknowledged listener) {
+ public void setOnMessageAcknowledgeListener(final OnMessageAcknowledged listener) {
this.acknowledgedListener = listener;
}
- public void addOnAdvancedStreamFeaturesAvailableListener(OnAdvancedStreamFeaturesLoaded listener) {
+ public void addOnAdvancedStreamFeaturesAvailableListener(final OnAdvancedStreamFeaturesLoaded listener) {
if (!this.advancedStreamFeaturesLoadedListeners.contains(listener)) {
this.advancedStreamFeaturesLoadedListeners.add(listener);
}
}
- public void disconnect(boolean force) {
+ public void disconnect(final boolean force) {
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting");
try {
if (force) {
@@ -973,23 +972,23 @@ public class XmppConnection implements Runnable {
}
tagWriter.writeTag(Tag.end("stream:stream"));
socket.close();
- } catch (IOException e) {
+ } catch (final IOException e) {
Log.d(Config.LOGTAG,
"io exception during disconnect");
- } catch (InterruptedException e) {
+ } catch (final InterruptedException e) {
Log.d(Config.LOGTAG, "interrupted");
}
}
}
}).start();
- } catch (IOException e) {
+ } catch (final IOException e) {
Log.d(Config.LOGTAG, "io exception during disconnect");
}
}
- public List<String> findDiscoItemsByFeature(String feature) {
+ public List<String> findDiscoItemsByFeature(final String feature) {
final List<String> items = new ArrayList<>();
- for (Entry<String, List<String>> cursor : disco.entrySet()) {
+ for (final Entry<String, List<String>> cursor : disco.entrySet()) {
if (cursor.getValue().contains(feature)) {
items.add(cursor.getKey());
}
@@ -997,8 +996,8 @@ public class XmppConnection implements Runnable {
return items;
}
- public String findDiscoItemByFeature(String feature) {
- List<String> items = findDiscoItemsByFeature(feature);
+ public String findDiscoItemByFeature(final String feature) {
+ final List<String> items = findDiscoItemsByFeature(feature);
if (items.size() >= 1) {
return items.get(0);
}
@@ -1010,8 +1009,7 @@ public class XmppConnection implements Runnable {
}
public String getMucServer() {
- final List<String> items = new ArrayList<>();
- for (Entry<String, List<String>> cursor : disco.entrySet()) {
+ for (final Entry<String, List<String>> cursor : disco.entrySet()) {
final List<String> value = cursor.getValue();
if (value.contains("http://jabber.org/protocol/muc") && !value.contains("jabber:iq:gateway") && !value.contains("siacs:no:muc")) {
return cursor.getKey();
@@ -1021,8 +1019,8 @@ public class XmppConnection implements Runnable {
}
public int getTimeToNextAttempt() {
- int interval = (int) (25 * Math.pow(1.5, attempt));
- int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000);
+ final int interval = (int) (25 * Math.pow(1.5, attempt));
+ final int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000);
return interval - secondsSinceLast;
}
@@ -1035,7 +1033,7 @@ public class XmppConnection implements Runnable {
}
public long getLastSessionEstablished() {
- long diff;
+ final long diff;
if (this.lastSessionStarted == 0) {
diff = SystemClock.elapsedRealtime() - this.lastConnect;
} else {
@@ -1067,7 +1065,7 @@ public class XmppConnection implements Runnable {
public class Features {
XmppConnection connection;
- public Features(XmppConnection connection) {
+ public Features(final XmppConnection connection) {
this.connection = connection;
}
@@ -1080,6 +1078,10 @@ public class XmppConnection implements Runnable {
return hasDiscoFeature(account.getServer(), "urn:xmpp:carbons:2");
}
+ public boolean blocking() {
+ return hasDiscoFeature(account.getServer(), Xmlns.BLOCKING);
+ }
+
public boolean sm() {
return streamId != null;
}
@@ -1110,4 +1112,8 @@ public class XmppConnection implements Runnable {
.findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null;
}
}
+
+ private IqGenerator getIqGenerator() {
+ return mXmppConnectionService.getIqGenerator();
+ }
}