From cc4f3702a83b5f4d4d57aa66bf50c5ba3b96e72b Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 15 Nov 2014 12:37:09 +0100 Subject: [PATCH] made file transfers cancelable --- .../conversations/entities/Downloadable.java | 2 + .../services/XmppConnectionService.java | 5 ++ .../ui/ConversationFragment.java | 17 ++++++- .../xmpp/jingle/JingleConnection.java | 48 ++++++++++++------- .../xmpp/jingle/JingleInbandTransport.java | 18 +++++-- .../xmpp/jingle/JingleTransport.java | 2 + src/main/res/menu/message_context.xml | 3 ++ src/main/res/values/strings.xml | 3 +- 8 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Downloadable.java b/src/main/java/eu/siacs/conversations/entities/Downloadable.java index d3e863ef5..d25bf93a8 100644 --- a/src/main/java/eu/siacs/conversations/entities/Downloadable.java +++ b/src/main/java/eu/siacs/conversations/entities/Downloadable.java @@ -23,4 +23,6 @@ public interface Downloadable { public int getProgress(); public String getMimeType(); + + public void cancel(); } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 4565ce30f..06137c642 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2040,5 +2040,10 @@ public class XmppConnectionService extends Service { return ""; } + @Override + public void cancel() { + + } + } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 63d740c32..e15a6bbc7 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -43,6 +43,7 @@ import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.Presences; @@ -343,6 +344,7 @@ public class ConversationFragment extends Fragment { MenuItem sendAgain = menu.findItem(R.id.send_again); MenuItem copyUrl = menu.findItem(R.id.copy_url); MenuItem downloadImage = menu.findItem(R.id.download_image); + MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission); if (this.selectedMessage.getType() != Message.TYPE_TEXT || this.selectedMessage.getDownloadable() != null) { copyText.setVisible(false); @@ -359,12 +361,15 @@ public class ConversationFragment extends Fragment { || this.selectedMessage.getImageParams().url == null) { copyUrl.setVisible(false); } - if (this.selectedMessage.getType() != Message.TYPE_TEXT || this.selectedMessage.getDownloadable() != null || !this.selectedMessage.bodyContainsDownloadable()) { downloadImage.setVisible(false); } + if (this.selectedMessage.getDownloadable() == null + || this.selectedMessage.getDownloadable().getStatus() == Downloadable.STATUS_DELETED) { + cancelTransmission.setVisible(false); + } } } @@ -386,6 +391,9 @@ public class ConversationFragment extends Fragment { case R.id.download_image: downloadImage(selectedMessage); return true; + case R.id.cancel_transmission: + cancelTransmission(selectedMessage); + return true; default: return super.onContextItemSelected(item); } @@ -428,6 +436,13 @@ public class ConversationFragment extends Fragment { .createNewConnection(message); } + private void cancelTransmission(Message message) { + Downloadable downloadable = message.getDownloadable(); + if (downloadable!=null) { + downloadable.cancel(); + } + } + protected void privateMessageWith(final Jid counterpart) { this.mEditMessage.setText(""); this.conversation.setNextCounterpart(counterpart); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 9a7e16f97..0db145036 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -10,7 +10,6 @@ import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import android.content.Intent; -import android.graphics.BitmapFactory; import android.net.Uri; import android.os.SystemClock; import android.util.Log; @@ -76,7 +75,7 @@ public class JingleConnection implements Downloadable { @Override public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() == IqPacket.TYPE_ERROR) { - cancel(); + fail(); } } }; @@ -115,7 +114,7 @@ public class JingleConnection implements Downloadable { @Override public void onFileTransferAborted() { JingleConnection.this.sendCancel(); - JingleConnection.this.cancel(); + JingleConnection.this.fail(); } }; @@ -162,14 +161,14 @@ public class JingleConnection implements Downloadable { Reason reason = packet.getReason(); if (reason != null) { if (reason.hasChild("cancel")) { - this.cancel(); + this.fail(); } else if (reason.hasChild("success")) { this.receiveSuccess(); } else { - this.cancel(); + this.fail(); } } else { - this.cancel(); + this.fail(); } } else if (packet.isAction("session-accept")) { returnResult = receiveAccept(packet); @@ -343,7 +342,7 @@ public class JingleConnection implements Downloadable { byte[] key = conversation.getSymmetricKey(); if (key == null) { this.sendCancel(); - this.cancel(); + this.fail(); return; } else { this.file.setKey(key); @@ -352,11 +351,11 @@ public class JingleConnection implements Downloadable { this.file.setExpectedSize(size); } else { this.sendCancel(); - this.cancel(); + this.fail(); } } else { this.sendCancel(); - this.cancel(); + this.fail(); } } @@ -495,7 +494,7 @@ public class JingleConnection implements Downloadable { } else { Log.d(Config.LOGTAG, "activated connection not found"); this.sendCancel(); - this.cancel(); + this.fail(); } } return true; @@ -542,7 +541,7 @@ public class JingleConnection implements Downloadable { this.transport = connection; if (connection == null) { Log.d(Config.LOGTAG, "could not find suitable candidate"); - this.disconnect(); + this.disconnectSocks5Connections(); if (this.initiator.equals(account.getJid())) { this.sendFallbackToIbb(); } @@ -633,7 +632,7 @@ public class JingleConnection implements Downloadable { reason.addChild("success"); packet.setReason(reason); this.sendJinglePacket(packet); - this.disconnect(); + this.disconnectSocks5Connections(); this.mJingleStatus = JINGLE_STATUS_FINISHED; this.message.setStatus(Message.STATUS_RECEIVED); this.message.setDownloadable(null); @@ -710,13 +709,30 @@ public class JingleConnection implements Downloadable { this.mJingleStatus = JINGLE_STATUS_FINISHED; this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND); - this.disconnect(); + this.disconnectSocks5Connections(); this.mJingleConnectionManager.finishConnection(this); } public void cancel() { - this.mJingleStatus = JINGLE_STATUS_CANCELED; - this.disconnect(); + this.disconnectSocks5Connections(); + if (this.transport != null && this.transport instanceof JingleInbandTransport) { + this.transport.disconnect(); + } + this.sendCancel(); + this.mJingleConnectionManager.finishConnection(this); + if (this.responder.equals(account.getJid())) { + this.mStatus = Downloadable.STATUS_FAILED; + this.mXmppConnectionService.updateConversationUi(); + } else { + this.mXmppConnectionService.markMessage(this.message, + Message.STATUS_SEND_FAILED); + this.message.setDownloadable(null); + } + } + + private void fail() { + this.mJingleStatus = JINGLE_STATUS_FAILED; + this.disconnectSocks5Connections(); if (this.message != null) { if (this.responder.equals(account.getJid())) { this.mStatus = Downloadable.STATUS_FAILED; @@ -772,7 +788,7 @@ public class JingleConnection implements Downloadable { }); } - private void disconnect() { + private void disconnectSocks5Connections() { Iterator> it = this.connections .entrySet().iterator(); while (it.hasNext()) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 791f48600..982fa9647 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -28,6 +28,8 @@ public class JingleInbandTransport extends JingleTransport { private boolean established = false; + private boolean connected = true; + private DownloadableFile file; private JingleConnection connection; @@ -42,7 +44,7 @@ public class JingleInbandTransport extends JingleTransport { private OnIqPacketReceived onAckReceived = new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { + if (connected && packet.getType() == IqPacket.TYPE_RESULT) { sendNextBlock(); } } @@ -64,7 +66,7 @@ public class JingleInbandTransport extends JingleTransport { open.setAttribute("sid", this.sessionId); open.setAttribute("stanza", "iq"); open.setAttribute("block-size", Integer.toString(this.blockSize)); - + this.connected = true; this.account.getXmppConnection().sendIqPacket(iq, new OnIqPacketReceived() { @@ -116,12 +118,19 @@ public class JingleInbandTransport extends JingleTransport { callback.onFileTransferAborted(); return; } - this.sendNextBlock(); + if (this.connected) { + this.sendNextBlock(); + } } catch (NoSuchAlgorithmException e) { callback.onFileTransferAborted(); } } + @Override + public void disconnect() { + this.connected = false; + } + private void sendNextBlock() { byte[] buffer = new byte[this.bufferSize]; try { @@ -183,13 +192,14 @@ public class JingleInbandTransport extends JingleTransport { if (payload.getName().equals("open")) { if (!established) { established = true; + connected = true; this.account.getXmppConnection().sendIqPacket( packet.generateRespone(IqPacket.TYPE_RESULT), null); } else { this.account.getXmppConnection().sendIqPacket( packet.generateRespone(IqPacket.TYPE_ERROR), null); } - } else if (payload.getName().equals("data")) { + } else if (connected && payload.getName().equals("data")) { this.receiveNextBlock(payload.getContent()); this.account.getXmppConnection().sendIqPacket( packet.generateRespone(IqPacket.TYPE_RESULT), null); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java index 1374e61cc..e832d3f58 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleTransport.java @@ -10,4 +10,6 @@ public abstract class JingleTransport { public abstract void send(final DownloadableFile file, final OnFileTransmissionStatusChanged callback); + + public abstract void disconnect(); } diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml index 80d4d1960..3be52442e 100644 --- a/src/main/res/menu/message_context.xml +++ b/src/main/res/menu/message_context.xml @@ -16,5 +16,8 @@ + \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 3b030e16c..5a01f8a64 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -318,5 +318,6 @@ sending (%1$d%% completed) Preparing file for transmission File offered for download - %s file; + %s file + Cancel transmission