diff --git a/src/main/java/eu/siacs/conversations/entities/Transferable.java b/src/main/java/eu/siacs/conversations/entities/Transferable.java index df18f3a2d..6a31a368a 100644 --- a/src/main/java/eu/siacs/conversations/entities/Transferable.java +++ b/src/main/java/eu/siacs/conversations/entities/Transferable.java @@ -15,6 +15,7 @@ public interface Transferable { int STATUS_DOWNLOADING = 0x204; int STATUS_OFFER_CHECK_FILESIZE = 0x206; int STATUS_UPLOADING = 0x207; + int STATUS_CANCELLED = 0x208; boolean start(); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 490bd0f4f..40cc740c0 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -188,7 +188,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie if (message.isFileOrImage() || transferable != null) { FileParams params = message.getFileParams(); filesize = params.size > 0 ? UIHelper.filesizeToString(params.size) : null; - if (transferable != null && transferable.getStatus() == Transferable.STATUS_FAILED) { + if (transferable != null && (transferable.getStatus() == Transferable.STATUS_FAILED || transferable.getStatus() == Transferable.STATUS_CANCELLED)) { error = true; } } @@ -207,10 +207,6 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie info = getContext().getString(R.string.offering); break; case Message.STATUS_SEND_RECEIVED: - if (mIndicateReceived) { - viewHolder.indicatorReceived.setVisibility(View.VISIBLE); - } - break; case Message.STATUS_SEND_DISPLAYED: if (mIndicateReceived) { viewHolder.indicatorReceived.setVisibility(View.VISIBLE); diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 84df63dc2..c99c1c1b2 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -274,6 +274,8 @@ public class UIHelper { getFileDescriptionString(context, message)), true); case Transferable.STATUS_FAILED: return new Pair<>(context.getString(R.string.file_transmission_failed), true); + case Transferable.STATUS_CANCELLED: + return new Pair<>(context.getString(R.string.file_transmission_cancelled), true); case Transferable.STATUS_UPLOADING: if (message.getStatus() == Message.STATUS_OFFERED) { return new Pair<>(context.getString(R.string.offering_x_file, 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 930458b2b..d7bc7db0c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -142,7 +142,7 @@ public class JingleConnection implements Transferable { @Override public void onFileTransferAborted() { - JingleConnection.this.sendCancel(); //TODO probably send connectivity error instead? + JingleConnection.this.sendSessionTerminate("connectivity-error"); JingleConnection.this.fail(); } }; @@ -227,12 +227,12 @@ public class JingleConnection implements Transferable { Reason reason = packet.getReason(); if (reason != null) { if (reason.hasChild("cancel")) { - //TODO mark as 'cancelled' + this.cancelled = true; this.fail(); } else if (reason.hasChild("success")) { this.receiveSuccess(); } else { - this.fail(); + this.fail(reason.getName()); } } else { this.fail(); @@ -411,8 +411,6 @@ public class JingleConnection implements Transferable { this.contentName = content.getAttribute("name"); this.transportId = content.getTransportId(); - //TODO change this to positive or negative response instead of fail directly - mXmppConnectionService.sendIqPacket(account, packet.generateResponse(IqPacket.TYPE.RESULT), null); if (this.initialTransport == Transport.SOCKS) { this.mergeCandidates(JingleCandidate.parse(content.socks5transport().getChildren())); @@ -423,20 +421,20 @@ public class JingleConnection implements Transferable { this.ibbBlockSize = Math.min(Integer.parseInt(receivedBlockSize), this.ibbBlockSize); } catch (NumberFormatException e) { Log.d(Config.LOGTAG, "number format exception " + e.getMessage()); - this.sendCancel(); + respondToIq(packet, false); this.fail(); return; } } else { Log.d(Config.LOGTAG, "received block size was null"); - this.sendCancel(); + respondToIq(packet, false); this.fail(); return; } } this.ftVersion = content.getVersion(); if (ftVersion == null) { - this.sendCancel(); + respondToIq(packet, false); this.fail(); return; } @@ -498,6 +496,9 @@ public class JingleConnection implements Transferable { //JET reports the plain text size. however lower levels of our receiving code still //expect the cipher text size. so we just + 16 bytes (auth tag size) here this.file.setExpectedSize(size + (remoteIsUsingJet ? 16 : 0)); + + respondToIq(packet, true); + if (mJingleConnectionManager.hasStoragePermission() && size < this.mJingleConnectionManager.getAutoAcceptFileSize() && mXmppConnectionService.isDataSaverDisabled()) { @@ -515,13 +516,9 @@ public class JingleConnection implements Transferable { this.mXmppConnectionService.getNotificationService().push(message); } Log.d(Config.LOGTAG, "receiving file: expecting size of " + this.file.getExpectedSize()); - } else { - this.sendCancel(); - this.fail(); + return; } - } else { - this.sendCancel(); - this.fail(); + respondToIq(packet, false); } } @@ -569,7 +566,7 @@ public class JingleConnection implements Transferable { try { this.mFileInputStream = new FileInputStream(file); } catch (FileNotFoundException e) { - abort(); + fail(e.getMessage()); return; } content.setTransportId(this.transportId); @@ -746,7 +743,7 @@ public class JingleConnection implements Transferable { connection.setActivated(true); } else { Log.d(Config.LOGTAG, "activated connection not found"); - this.sendCancel(); + sendSessionTerminate("failed-transport"); this.fail(); } } @@ -884,11 +881,7 @@ public class JingleConnection implements Transferable { } private void sendSuccess() { - JinglePacket packet = bootstrapPacket("session-terminate"); - Reason reason = new Reason(); - reason.addChild("success"); - packet.setReason(reason); - this.sendJinglePacket(packet); + sendSessionTerminate("success"); this.disconnectSocks5Connections(); this.mJingleStatus = JINGLE_STATUS_FINISHED; this.message.setStatus(Message.STATUS_RECEIVED); @@ -999,18 +992,18 @@ public class JingleConnection implements Transferable { @Override public void cancel() { this.cancelled = true; - abort(); + abort("cancel"); } - public void abort() { + void abort(final String reason) { this.disconnectSocks5Connections(); if (this.transport instanceof JingleInbandTransport) { this.transport.disconnect(); } - this.sendCancel(); + sendSessionTerminate(reason); this.mJingleConnectionManager.finishConnection(this); if (responding()) { - this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED)); + this.message.setTransferable(new TransferablePlaceholder(cancelled ? Transferable.STATUS_CANCELLED : Transferable.STATUS_FAILED)); if (this.file != null) { file.delete(); } @@ -1035,7 +1028,7 @@ public class JingleConnection implements Transferable { FileBackend.close(mFileOutputStream); if (this.message != null) { if (responding()) { - this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED)); + this.message.setTransferable(new TransferablePlaceholder(cancelled ? Transferable.STATUS_CANCELLED : Transferable.STATUS_FAILED)); if (this.file != null) { file.delete(); } @@ -1050,11 +1043,11 @@ public class JingleConnection implements Transferable { this.mJingleConnectionManager.finishConnection(this); } - private void sendCancel() { - JinglePacket packet = bootstrapPacket("session-terminate"); - Reason reason = new Reason(); - reason.addChild("cancel"); - packet.setReason(reason); + private void sendSessionTerminate(String reason) { + final JinglePacket packet = bootstrapPacket("session-terminate"); + final Reason r = new Reason(); + r.addChild(reason); + packet.setReason(r); this.sendJinglePacket(packet); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 932d635e7..f354c25af 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -166,7 +166,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { public void cancelInTransmission() { for (JingleConnection connection : this.connections) { if (connection.getJingleStatus() == JingleConnection.JINGLE_STATUS_TRANSMITTING) { - connection.abort(); + connection.abort("connectivity-error"); } } } 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 ac22614f8..b4e5039aa 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -48,10 +48,15 @@ public class JingleInbandTransport extends JingleTransport { private OnIqPacketReceived onAckReceived = new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (connected && packet.getType() == IqPacket.TYPE.RESULT) { + if (!connected) { + return; + } + if (packet.getType() == IqPacket.TYPE.RESULT) { if (remainingSize > 0) { sendNextBlock(); } + } else if (packet.getType() == IqPacket.TYPE.ERROR) { + onFileTransmissionStatusChanged.onFileTransferAborted(); } } };