diff options
author | steckbrief <steckbrief@chefmail.de> | 2015-03-30 22:12:49 +0200 |
---|---|---|
committer | steckbrief <steckbrief@chefmail.de> | 2015-03-30 22:12:49 +0200 |
commit | 75c5275f7e9a27019b9517770603ca4c77f1fbd9 (patch) | |
tree | 567d10bd9e559089487f5627c436000e2a1a8fc8 /src/main/java/eu/siacs/conversations/xmpp | |
parent | c8fe93cf0a99481bfe7a30bbc1cd98383205bcaa (diff) | |
parent | 7eabdfd80f50634282307f45c5f99ab46181805d (diff) |
Merge tag '1.2.0' into trz/master
Conflicts:
src/main/java/eu/siacs/conversations/parser/AbstractParser.java
src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
src/main/res/values-de/strings.xml
src/main/res/xml/preferences.xml
Diffstat (limited to 'src/main/java/eu/siacs/conversations/xmpp')
5 files changed, 126 insertions, 33 deletions
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 19e271b2..48dc2150 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -242,6 +242,13 @@ public class XmppConnection implements Runnable { @Override public void run() { + try { + if (socket != null) { + socket.close(); + } + } catch (final IOException ignored) { + + } connect(); } @@ -515,8 +522,9 @@ public class XmppConnection implements Runnable { sslSocket.setEnabledProtocols(supportProtocols); - final String[] cipherSuites = CryptoHelper.getSupportedCipherSuites( + final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites( sslSocket.getSupportedCipherSuites()); + //Log.d(Config.LOGTAG, "Using ciphers: " + Arrays.toString(cipherSuites)); if (cipherSuites.length > 0) { sslSocket.setEnabledCipherSuites(cipherSuites); } @@ -658,6 +666,12 @@ public class XmppConnection implements Runnable { } private void sendBindRequest() { + while(!mXmppConnectionService.areMessagesInitialized()) { + try { + Thread.sleep(500); + } catch (final InterruptedException ignored) { + } + } final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind") .addChild("resource").setContent(account.getResource()); @@ -673,28 +687,11 @@ public class XmppConnection implements Runnable { } catch (final InvalidJidException e) { // TODO: Handle the case where an external JID is technically invalid? } - if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) { - smVersion = 3; - final EnablePacket enable = new EnablePacket(smVersion); - tagWriter.writeStanzaAsync(enable); - stanzasSent = 0; - messageReceipts.clear(); - } else if (streamFeatures.hasChild("sm", "urn:xmpp:sm:2")) { - smVersion = 2; - final EnablePacket enable = new EnablePacket(smVersion); - tagWriter.writeStanzaAsync(enable); - stanzasSent = 0; - messageReceipts.clear(); - } - features.carbonsEnabled = false; - features.blockListRequested = false; - disco.clear(); - sendServiceDiscoveryInfo(account.getServer()); - sendServiceDiscoveryItems(account.getServer()); - if (bindListener != null) { - bindListener.onBind(account); + if (streamFeatures.hasChild("session")) { + sendStartSession(); + } else { + sendPostBindInitialization(); } - sendInitialPing(); } else { disconnect(true); } @@ -703,12 +700,45 @@ public class XmppConnection implements Runnable { } } }); - if (this.streamFeatures.hasChild("session")) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": sending deprecated session"); - final IqPacket startSession = new IqPacket(IqPacket.TYPE.SET); - startSession.addChild("session","urn:ietf:params:xml:ns:xmpp-session"); - this.sendUnmodifiedIqPacket(startSession, null); + } + + private void sendStartSession() { + final IqPacket startSession = new IqPacket(IqPacket.TYPE.SET); + startSession.addChild("session","urn:ietf:params:xml:ns:xmpp-session"); + this.sendUnmodifiedIqPacket(startSession, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + sendPostBindInitialization(); + } else { + disconnect(true); + } + } + }); + } + + private void sendPostBindInitialization() { + smVersion = 0; + if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) { + smVersion = 3; + } else if (streamFeatures.hasChild("sm", "urn:xmpp:sm:2")) { + smVersion = 2; + } + if (smVersion != 0) { + final EnablePacket enable = new EnablePacket(smVersion); + tagWriter.writeStanzaAsync(enable); + stanzasSent = 0; + messageReceipts.clear(); } + features.carbonsEnabled = false; + features.blockListRequested = false; + disco.clear(); + sendServiceDiscoveryInfo(account.getServer()); + sendServiceDiscoveryItems(account.getServer()); + if (bindListener != null) { + bindListener.onBind(account); + } + sendInitialPing(); } private void sendServiceDiscoveryInfo(final Jid server) { @@ -1027,6 +1057,11 @@ public class XmppConnection implements Runnable { this.sendPacket(new InactivePacket()); } + public void resetAttemptCount() { + this.attempt = 0; + this.lastConnect = 0; + } + public class Features { XmppConnection connection; private boolean carbonsEnabled = false; diff --git a/src/main/java/eu/siacs/conversations/xmpp/chatstate/ChatState.java b/src/main/java/eu/siacs/conversations/xmpp/chatstate/ChatState.java new file mode 100644 index 00000000..f85efbdb --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/chatstate/ChatState.java @@ -0,0 +1,32 @@ +package eu.siacs.conversations.xmpp.chatstate; + +import eu.siacs.conversations.xml.Element; + +public enum ChatState { + + ACTIVE, INACTIVE, GONE, COMPOSING, PAUSED, mIncomingChatState; + + public static ChatState parse(Element element) { + final String NAMESPACE = "http://jabber.org/protocol/chatstates"; + if (element.hasChild("active",NAMESPACE)) { + return ACTIVE; + } else if (element.hasChild("inactive",NAMESPACE)) { + return INACTIVE; + } else if (element.hasChild("composing",NAMESPACE)) { + return COMPOSING; + } else if (element.hasChild("gone",NAMESPACE)) { + return GONE; + } else if (element.hasChild("paused",NAMESPACE)) { + return PAUSED; + } else { + return null; + } + } + + public static Element toElement(ChatState state) { + final String NAMESPACE = "http://jabber.org/protocol/chatstates"; + final Element element = new Element(state.toString().toLowerCase()); + element.setAttribute("xmlns",NAMESPACE); + return element; + } +} diff --git a/src/main/java/eu/siacs/conversations/xmpp/jid/InvalidJidException.java b/src/main/java/eu/siacs/conversations/xmpp/jid/InvalidJidException.java index f1855263..164e8849 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jid/InvalidJidException.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jid/InvalidJidException.java @@ -8,6 +8,7 @@ public class InvalidJidException extends Exception { public final static String INVALID_PART_LENGTH = "JID part must be between 0 and 1023 characters"; public final static String INVALID_CHARACTER = "JID contains an invalid character"; public final static String STRINGPREP_FAIL = "The STRINGPREP operation has failed for the given JID"; + public final static String IS_NULL = "JID can not be NULL"; /** * Constructs a new {@code Exception} that includes the current stack trace. diff --git a/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java b/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java index a35ea37c..295e067a 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java @@ -1,9 +1,12 @@ package eu.siacs.conversations.xmpp.jid; +import android.util.LruCache; + import net.java.otr4j.session.SessionID; import java.net.IDN; +import eu.siacs.conversations.Config; import gnu.inet.encoding.Stringprep; import gnu.inet.encoding.StringprepException; @@ -12,6 +15,8 @@ import gnu.inet.encoding.StringprepException; */ public final class Jid { + private static LruCache<String,Jid> cache = new LruCache<>(1024); + private final String localpart; private final String domainpart; private final String resourcepart; @@ -41,7 +46,11 @@ public final class Jid { } public static Jid fromString(final String jid) throws InvalidJidException { - return new Jid(jid); + return Jid.fromString(jid, false); + } + + public static Jid fromString(final String jid, final boolean safe) throws InvalidJidException { + return new Jid(jid, safe); } public static Jid fromParts(final String localpart, @@ -56,10 +65,21 @@ public final class Jid { if (resourcepart != null && !resourcepart.isEmpty()) { out = out + "/" + resourcepart; } - return new Jid(out); + return new Jid(out, false); } - private Jid(final String jid) throws InvalidJidException { + private Jid(final String jid, final boolean safe) throws InvalidJidException { + if (jid == null) throw new InvalidJidException(InvalidJidException.IS_NULL); + + Jid fromCache = Jid.cache.get(jid); + if (fromCache != null) { + displayjid = fromCache.displayjid; + localpart = fromCache.localpart; + domainpart = fromCache.domainpart; + resourcepart = fromCache.resourcepart; + return; + } + // Hackish Android way to count the number of chars in a string... should work everywhere. final int atCount = jid.length() - jid.replace("@", "").length(); final int slashCount = jid.length() - jid.replace("/", "").length(); @@ -88,7 +108,7 @@ public final class Jid { } else { final String lp = jid.substring(0, atLoc); try { - localpart = Stringprep.nodeprep(lp); + localpart = Config.DISABLE_STRING_PREP || safe ? lp : Stringprep.nodeprep(lp); } catch (final StringprepException e) { throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e); } @@ -103,7 +123,7 @@ public final class Jid { if (slashCount > 0) { final String rp = jid.substring(slashLoc + 1, jid.length()); try { - resourcepart = Stringprep.resourceprep(rp); + resourcepart = Config.DISABLE_STRING_PREP || safe ? rp : Stringprep.resourceprep(rp); } catch (final StringprepException e) { throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e); } @@ -139,6 +159,8 @@ public final class Jid { throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH); } + Jid.cache.put(jid, this); + this.displayjid = finaljid; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java b/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java index 4e7b532b..93aaa68c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java +++ b/src/main/java/eu/siacs/conversations/xmpp/stanzas/MessagePacket.java @@ -26,7 +26,7 @@ public class MessagePacket extends AbstractStanza { this.children.remove(findChild("body")); Element body = new Element("body"); body.setContent(text); - this.children.add(body); + this.children.add(0, body); } public void setType(int type) { @@ -39,6 +39,9 @@ public class MessagePacket extends AbstractStanza { break; case TYPE_NORMAL: break; + case TYPE_ERROR: + this.setAttribute("type","error"); + break; default: this.setAttribute("type", "chat"); break; |