aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/de/pixart/messenger/entities/Transferable.java3
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java9
-rw-r--r--src/main/java/de/pixart/messenger/utils/UIHelper.java9
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java167
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java2
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java7
-rw-r--r--src/main/res/values/strings.xml1
7 files changed, 114 insertions, 84 deletions
diff --git a/src/main/java/de/pixart/messenger/entities/Transferable.java b/src/main/java/de/pixart/messenger/entities/Transferable.java
index 054841b6e..968563b32 100644
--- a/src/main/java/de/pixart/messenger/entities/Transferable.java
+++ b/src/main/java/de/pixart/messenger/entities/Transferable.java
@@ -19,6 +19,7 @@ public interface Transferable {
"otr"
);
+ int STATUS_WAITING = 0x199;
int STATUS_UNKNOWN = 0x200;
int STATUS_CHECKING = 0x201;
int STATUS_FAILED = 0x202;
@@ -26,7 +27,7 @@ public interface Transferable {
int STATUS_DOWNLOADING = 0x204;
int STATUS_OFFER_CHECK_FILESIZE = 0x206;
int STATUS_UPLOADING = 0x207;
- int STATUS_WAITING = 0x199;
+ int STATUS_CANCELLED = 0x208;
boolean start();
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
index 6cff1aebd..d11a2af0f 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
@@ -9,10 +9,6 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.net.Uri;
import android.preference.PreferenceManager;
-
-import androidx.core.app.ActivityCompat;
-import androidx.core.content.ContextCompat;
-
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
@@ -39,6 +35,9 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
import com.google.common.base.Strings;
import com.squareup.picasso.Picasso;
@@ -230,7 +229,7 @@ public class MessageAdapter extends ArrayAdapter<Message> 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;
}
}
diff --git a/src/main/java/de/pixart/messenger/utils/UIHelper.java b/src/main/java/de/pixart/messenger/utils/UIHelper.java
index 102848183..e081ae6d6 100644
--- a/src/main/java/de/pixart/messenger/utils/UIHelper.java
+++ b/src/main/java/de/pixart/messenger/utils/UIHelper.java
@@ -1,12 +1,13 @@
package de.pixart.messenger.utils;
import android.content.Context;
-import androidx.annotation.ColorInt;
import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.Pair;
+import androidx.annotation.ColorInt;
+
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.Arrays;
@@ -269,6 +270,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,
@@ -315,12 +318,12 @@ public class UIHelper {
continue;
}
char first = l.charAt(0);
- if ((first != '>' || !isPositionFollowedByQuoteableCharacter(l,0)) && first != '\u00bb') {
+ if ((first != '>' || !isPositionFollowedByQuoteableCharacter(l, 0)) && first != '\u00bb') {
CharSequence line = CharSequenceUtils.trim(l);
if (line.length() == 0) {
continue;
}
- char last = line.charAt(line.length()-1);
+ char last = line.charAt(line.length() - 1);
if (builder.length() != 0) {
builder.append(' ');
}
diff --git a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
index 561404186..bfaeacc31 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
@@ -12,6 +12,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -143,7 +144,7 @@ public class JingleConnection implements Transferable {
@Override
public void onFileTransferAborted() {
- JingleConnection.this.sendCancel();
+ JingleConnection.this.sendSessionTerminate("connectivity-error");
JingleConnection.this.fail();
}
};
@@ -223,27 +224,27 @@ public class JingleConnection implements Transferable {
return this.message.getCounterpart();
}
- public void deliverPacket(JinglePacket packet) {
- boolean returnResult = true;
+ void deliverPacket(JinglePacket packet) {
if (packet.isAction("session-terminate")) {
Reason reason = packet.getReason();
if (reason != null) {
if (reason.hasChild("cancel")) {
+ this.cancelled = true;
this.fail();
} else if (reason.hasChild("success")) {
this.receiveSuccess();
} else {
- this.fail();
+ this.fail(reason.getName());
}
} else {
this.fail();
}
} else if (packet.isAction("session-accept")) {
- returnResult = receiveAccept(packet);
+ receiveAccept(packet);
} else if (packet.isAction("session-info")) {
- Element checksum = packet.getChecksum();
- Element file = checksum == null ? null : checksum.findChild("file");
- Element hash = file == null ? null : file.findChild("hash", "urn:xmpp:hashes:2");
+ final Element checksum = packet.getChecksum();
+ final Element file = checksum == null ? null : checksum.findChild("file");
+ final Element hash = file == null ? null : file.findChild("hash", "urn:xmpp:hashes:2");
if (hash != null && "sha-1".equalsIgnoreCase(hash.getAttribute("algo"))) {
try {
this.expectedHash = Base64.decode(hash.getContent(), Base64.DEFAULT);
@@ -251,27 +252,28 @@ public class JingleConnection implements Transferable {
this.expectedHash = new byte[0];
}
}
+ respondToIq(packet, true);
} else if (packet.isAction("transport-info")) {
- returnResult = receiveTransportInfo(packet);
+ receiveTransportInfo(packet);
} else if (packet.isAction("transport-replace")) {
if (packet.getJingleContent().hasIbbTransport()) {
- returnResult = this.receiveFallbackToIbb(packet);
+ receiveFallbackToIbb(packet);
} else {
- returnResult = false;
- Log.d(Config.LOGTAG, "trying to fallback to something unknown"
- + packet.toString());
+ Log.d(Config.LOGTAG, "trying to fallback to something unknown" + packet.toString());
+ respondToIq(packet, false);
}
} else if (packet.isAction("transport-accept")) {
- returnResult = this.receiveTransportAccept(packet);
+ receiveTransportAccept(packet);
} else {
- Log.d(Config.LOGTAG, "packet arrived in connection. action was "
- + packet.getAction());
- returnResult = false;
+ Log.d(Config.LOGTAG, "packet arrived in connection. action was " + packet.getAction());
+ respondToIq(packet, false);
}
- IqPacket response;
- if (returnResult) {
- response = packet.generateResponse(IqPacket.TYPE.RESULT);
+ }
+ private void respondToIq(final IqPacket packet, final boolean result) {
+ final IqPacket response;
+ if (result) {
+ response = packet.generateResponse(IqPacket.TYPE.RESULT);
} else {
response = packet.generateResponse(IqPacket.TYPE.ERROR);
final Element error = response.addChild("error").setAttribute("type", "cancel");
@@ -280,6 +282,14 @@ public class JingleConnection implements Transferable {
mXmppConnectionService.sendIqPacket(account, response, null);
}
+ private void respondToIqWithOutOfOrder(final IqPacket packet) {
+ final IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR);
+ final Element error = response.addChild("error").setAttribute("type", "wait");
+ error.addChild("unexpected-request", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ error.addChild("out-of-order", "urn:xmpp:jingle:errors:1");
+ mXmppConnectionService.sendIqPacket(account, response, null);
+ }
+
public void init(final Message message) {
if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
Conversation conversation = (Conversation) message.getConversation();
@@ -323,7 +333,7 @@ public class JingleConnection implements Transferable {
@Override
public void failed() {
- Log.d(Config.LOGTAG, "connection to our own proxy65 candidete failed");
+ Log.d(Config.LOGTAG, String.format("connection to our own proxy65 candidate failed (%s:%d)", candidate.getHost(), candidate.getPort()));
sendInitRequest();
}
@@ -341,6 +351,7 @@ public class JingleConnection implements Transferable {
}
});
}
+
}
private void gatherAndConnectDirectCandidates() {
@@ -402,8 +413,6 @@ public class JingleConnection implements Transferable {
this.contentName = content.getAttribute("name");
this.transportId = content.getTransportId();
- mXmppConnectionService.sendIqPacket(account, packet.generateResponse(IqPacket.TYPE.RESULT), null);
-
if (this.initialTransport == Transport.SOCKS) {
this.mergeCandidates(JingleCandidate.parse(content.socks5transport().getChildren()));
} else if (this.initialTransport == Transport.IBB) {
@@ -413,20 +422,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;
}
@@ -451,14 +460,26 @@ public class JingleConnection implements Transferable {
AbstractConnectionManager.Extension extension = AbstractConnectionManager.Extension.of(path);
if (VALID_IMAGE_EXTENSIONS.contains(extension.main)) {
message.setType(Message.TYPE_IMAGE);
- message.setRelativeFilePath(message.getUuid() + "." + extension.main);
+ if (message.getStatus() == Message.STATUS_RECEIVED) {
+ message.setRelativeFilePath(fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + "." + extension.main);
+ } else {
+ message.setRelativeFilePath("Sent/" + fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + "." + extension.main);
+ }
} else if (VALID_CRYPTO_EXTENSIONS.contains(extension.main)) {
if (VALID_IMAGE_EXTENSIONS.contains(extension.secondary)) {
message.setType(Message.TYPE_IMAGE);
- message.setRelativeFilePath(message.getUuid() + "." + extension.secondary);
+ if (message.getStatus() == Message.STATUS_RECEIVED) {
+ message.setRelativeFilePath(fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + "." + extension.secondary);
+ } else {
+ message.setRelativeFilePath("Sent/" + fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + "." + extension.secondary);
+ }
} else {
message.setType(Message.TYPE_FILE);
- message.setRelativeFilePath(message.getUuid() + (extension.secondary != null ? ("." + extension.secondary) : ""));
+ if (message.getStatus() == Message.STATUS_RECEIVED) {
+ message.setRelativeFilePath(fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + (extension.secondary != null ? ("." + extension.secondary) : ""));
+ } else {
+ message.setRelativeFilePath("Sent/" + fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + (extension.secondary != null ? ("." + extension.secondary) : ""));
+ }
}
// only for OTR compatibility
if (extension.main.equals("otr")) {
@@ -468,7 +489,11 @@ public class JingleConnection implements Transferable {
}
} else {
message.setType(Message.TYPE_FILE);
- message.setRelativeFilePath(message.getUuid() + (extension.main != null ? ("." + extension.main) : ""));
+ if (message.getStatus() == Message.STATUS_RECEIVED) {
+ message.setRelativeFilePath(fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + (extension.main != null ? ("." + extension.main) : ""));
+ } else {
+ message.setRelativeFilePath("Sent/" + fileDateFormat.format(new Date(message.getTimeSent())) + "_" + message.getUuid().substring(0, 4) + (extension.main != null ? ("." + extension.main) : ""));
+ }
}
long size = parseLong(fileSize, 0);
message.setBody(Long.toString(size));
@@ -491,6 +516,7 @@ 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()) {
@@ -508,13 +534,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);
}
}
@@ -562,7 +584,7 @@ public class JingleConnection implements Transferable {
try {
this.mFileInputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
- abort();
+ fail(e.getMessage());
return;
}
content.setTransportId(this.transportId);
@@ -642,7 +664,7 @@ public class JingleConnection implements Transferable {
@Override
public void established() {
- Log.d(Config.LOGTAG, "connected to proxy candidate");
+ Log.d(Config.LOGTAG, "connected to proxy65 candidate");
mergeCandidate(candidate);
content.socks5transport().setChildren(getCandidatesAsElements());
packet.setContent(content);
@@ -690,18 +712,19 @@ public class JingleConnection implements Transferable {
mXmppConnectionService.sendIqPacket(account, packet, callback);
}
- private boolean receiveAccept(JinglePacket packet) {
+ private void receiveAccept(JinglePacket packet) {
if (this.mJingleStatus != JINGLE_STATUS_INITIATED) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received out of order session-accept");
- return false;
+ respondToIqWithOutOfOrder(packet);
+ return;
}
this.mJingleStatus = JINGLE_STATUS_ACCEPTED;
mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND);
Content content = packet.getJingleContent();
if (content.hasSocks5Transport()) {
+ respondToIq(packet, true);
mergeCandidates(JingleCandidate.parse(content.socks5transport().getChildren()));
this.connectNextCandidate();
- return true;
} else if (content.hasIbbTransport()) {
String receivedBlockSize = packet.getJingleContent().ibbTransport().getAttribute("block-size");
if (receivedBlockSize != null) {
@@ -714,18 +737,19 @@ public class JingleConnection implements Transferable {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to parse block size in session-accept");
}
}
+ respondToIq(packet, true);
this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize);
this.transport.connect(onIbbTransportConnected);
- return true;
} else {
- return false;
+ respondToIq(packet, false);
}
}
- private boolean receiveTransportInfo(JinglePacket packet) {
- Content content = packet.getJingleContent();
+ private void receiveTransportInfo(JinglePacket packet) {
+ final Content content = packet.getJingleContent();
if (content.hasSocks5Transport()) {
if (content.socks5transport().hasChild("activated")) {
+ respondToIq(packet, true);
if ((this.transport != null) && (this.transport instanceof JingleSocks5Transport)) {
onProxyActivated.success();
} else {
@@ -737,21 +761,20 @@ public class JingleConnection implements Transferable {
connection.setActivated(true);
} else {
Log.d(Config.LOGTAG, "activated connection not found");
- this.sendCancel();
+ sendSessionTerminate("failed-transport");
this.fail();
}
}
- return true;
} else if (content.socks5transport().hasChild("proxy-error")) {
+ respondToIq(packet, true);
onProxyActivated.failed();
- return true;
} else if (content.socks5transport().hasChild("candidate-error")) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received candidate error");
+ respondToIq(packet, true);
this.receivedCandidate = true;
if (mJingleStatus == JINGLE_STATUS_ACCEPTED && this.sentCandidate) {
this.connect();
}
- return true;
} else if (content.socks5transport().hasChild("candidate-used")) {
String cid = content.socks5transport().findChild("candidate-used").getAttribute("cid");
if (cid != null) {
@@ -759,8 +782,10 @@ public class JingleConnection implements Transferable {
JingleCandidate candidate = getCandidate(cid);
if (candidate == null) {
Log.d(Config.LOGTAG, "could not find candidate with cid=" + cid);
- return false;
+ respondToIq(packet, false);
+ return;
}
+ respondToIq(packet, true);
candidate.flagAsUsedByCounterpart();
this.receivedCandidate = true;
if (mJingleStatus == JINGLE_STATUS_ACCEPTED && this.sentCandidate) {
@@ -768,15 +793,14 @@ public class JingleConnection implements Transferable {
} else {
Log.d(Config.LOGTAG, "ignoring because file is already in transmission or we haven't sent our candidate yet status=" + mJingleStatus + " sentCandidate=" + sentCandidate);
}
- return true;
} else {
- return false;
+ respondToIq(packet, false);
}
} else {
- return false;
+ respondToIq(packet, false);
}
} else {
- return true;
+ respondToIq(packet, true);
}
}
@@ -875,11 +899,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);
@@ -901,7 +921,7 @@ public class JingleConnection implements Transferable {
}
- private boolean receiveFallbackToIbb(JinglePacket packet) {
+ private void receiveFallbackToIbb(JinglePacket packet) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": receiving fallback to ibb");
final String receivedBlockSize = packet.getJingleContent().ibbTransport().getAttribute("block-size");
if (receivedBlockSize != null) {
@@ -924,6 +944,7 @@ public class JingleConnection implements Transferable {
content.ibbTransport().setAttribute("sid", this.transportId);
answer.setContent(content);
+ respondToIq(packet, true);
if (initiating()) {
this.sendJinglePacket(answer, (account, response) -> {
@@ -936,10 +957,9 @@ public class JingleConnection implements Transferable {
this.transport.receive(file, onFileTransmissionStatusChanged);
this.sendJinglePacket(answer);
}
- return true;
}
- private boolean receiveTransportAccept(JinglePacket packet) {
+ private void receiveTransportAccept(JinglePacket packet) {
if (packet.getJingleContent().hasIbbTransport()) {
final Element ibbTransport = packet.getJingleContent().ibbTransport();
final String receivedBlockSize = ibbTransport.getAttribute("block-size");
@@ -955,19 +975,20 @@ public class JingleConnection implements Transferable {
}
}
this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize);
+
if (sid == null || !sid.equals(this.transportId)) {
Log.w(Config.LOGTAG, String.format("%s: sid in transport-accept (%s) did not match our sid (%s) ", account.getJid().asBareJid(), sid, transportId));
}
+ respondToIq(packet, true);
//might be receive instead if we are not initiating
if (initiating()) {
this.transport.connect(onIbbTransportConnected);
} else {
this.transport.receive(file, onFileTransmissionStatusChanged);
}
- return true;
} else {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received invalid transport-accept");
- return false;
+ respondToIq(packet, false);
}
}
@@ -989,18 +1010,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();
}
@@ -1040,11 +1061,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/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java
index addd350d2..8faf5fbc1 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnectionManager.java
+++ b/src/main/java/de/pixart/messenger/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/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java
index 30986ca0c..744a72548 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java
@@ -47,10 +47,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();
}
}
};
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 24daff1c9..f3a5071a8 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -973,4 +973,5 @@
<string name="intro_privacy">Your privacy\nYour sovereignty</string>
<string name="intro_desc_privacy">Pix-Art Messenger will neither sell nor analyze your data and you decide which permissions you grant.</string>
<string name="no_results">No results</string>
+ <string name="file_transmission_cancelled">file transmission cancelled</string>
</resources>