diff options
Diffstat (limited to 'src/eu/siacs/conversations/xmpp/XmppConnection.java')
-rw-r--r-- | src/eu/siacs/conversations/xmpp/XmppConnection.java | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index 9fd435d1..932b16f2 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -31,6 +31,7 @@ import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.SystemClock; import android.util.Log; +import android.util.SparseArray; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; @@ -76,6 +77,7 @@ public class XmppConnection implements Runnable { private String streamId = null; private int smVersion = 3; + private SparseArray<String> messageReceipts = new SparseArray<String>(); private boolean usingCompression = false; @@ -100,6 +102,7 @@ public class XmppConnection implements Runnable { private OnMessagePacketReceived messageListener = null; private OnStatusChanged statusListener = null; private OnBindListener bindListener = null; + private OnMessageAcknowledged acknowledgedListener = null; private MemorizingTrustManager mMemorizingTrustManager; public XmppConnection(Account account, XmppConnectionService service) { @@ -250,7 +253,6 @@ public class XmppConnection implements Runnable { challange,mRandom)); tagWriter.writeElement(response); } else if (nextTag.isStart("enabled")) { - this.stanzasSent = 0; Element enabled = tagReader.readElement(nextTag); if ("true".equals(enabled.getAttribute("resume"))) { this.streamId = enabled.getAttribute("id"); @@ -266,9 +268,27 @@ public class XmppConnection implements Runnable { tagWriter.writeStanzaAsync(r); } else if (nextTag.isStart("resumed")) { lastPaketReceived = SystemClock.elapsedRealtime(); - Log.d(LOGTAG, account.getJid() + ": session resumed"); - tagReader.readElement(nextTag); - sendPing(); + Element resumed = tagReader.readElement(nextTag); + String h = resumed.getAttribute("h"); + try { + int serverCount = Integer.parseInt(h); + if (serverCount!=stanzasSent) { + Log.d(LOGTAG,account.getJid() + ": session resumed with lost packages"); + stanzasSent = serverCount; + } else { + Log.d(LOGTAG, account.getJid() + ": session resumed"); + } + if (acknowledgedListener!=null) { + for(int i = 0; i < messageReceipts.size(); ++i) { + if (serverCount>=messageReceipts.keyAt(i)) { + acknowledgedListener.onMessageAcknowledged(account, messageReceipts.valueAt(i)); + } + } + } + messageReceipts.clear(); + } catch (NumberFormatException e) { + + } changeStatus(Account.STATUS_ONLINE); } else if (nextTag.isStart("r")) { tagReader.readElement(nextTag); @@ -278,8 +298,12 @@ public class XmppConnection implements Runnable { Element ack = tagReader.readElement(nextTag); lastPaketReceived = SystemClock.elapsedRealtime(); int serverSequence = Integer.parseInt(ack.getAttribute("h")); - if (serverSequence > this.stanzasSent) { - this.stanzasSent = serverSequence; + String msgId = this.messageReceipts.get(serverSequence); + if (msgId != null) { + if (this.acknowledgedListener != null) { + this.acknowledgedListener.onMessageAcknowledged(account, msgId); + } + this.messageReceipts.remove(serverSequence); } } else if (nextTag.isStart("failed")) { tagReader.readElement(nextTag); @@ -612,10 +636,14 @@ public class XmppConnection implements Runnable { smVersion = 3; EnablePacket enable = new EnablePacket(smVersion); tagWriter.writeStanzaAsync(enable); + stanzasSent = 0; + messageReceipts.clear(); } else if (streamFeatures.hasChild("sm", "urn:xmpp:sm:2")) { smVersion = 2; EnablePacket enable = new EnablePacket(smVersion); tagWriter.writeStanzaAsync(enable); + stanzasSent = 0; + messageReceipts.clear(); } sendServiceDiscoveryInfo(account.getServer()); sendServiceDiscoveryItems(account.getServer()); @@ -753,9 +781,15 @@ public class XmppConnection implements Runnable { private synchronized void sendPacket(final AbstractStanza packet, PacketReceived callback) { - // TODO dont increment stanza count if packet = request packet or ack; - ++stanzasSent; + if (packet.getName().equals("iq") || packet.getName().equals("message") || packet.getName().equals("presence")) { + ++stanzasSent; + } tagWriter.writeStanzaAsync(packet); + if (packet instanceof MessagePacket && packet.getId() != null && this.streamId != null) { + Log.d(LOGTAG,"request delivery report for stanza "+stanzasSent); + this.messageReceipts.put(stanzasSent, packet.getId()); + tagWriter.writeStanzaAsync(new RequestPacket(this.smVersion)); + } if (callback != null) { if (packet.getId() == null) { packet.setId(nextRandomId()); @@ -803,6 +837,10 @@ public class XmppConnection implements Runnable { public void setOnBindListener(OnBindListener listener) { this.bindListener = listener; } + + public void setOnMessageAcknowledgeListener(OnMessageAcknowledged listener) { + this.acknowledgedListener = listener; + } public void disconnect(boolean force) { changeStatus(Account.STATUS_OFFLINE); |