diff --git a/res/values/strings.xml b/res/values/strings.xml index 40715a06..dc875349 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -248,4 +248,5 @@ Touch to edit conference details OpenPGP encrypted messages found Click here to enter passphrase and decrypt messages + Reception failed \ No newline at end of file diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java index 1e82fe6a..8e669c65 100644 --- a/src/eu/siacs/conversations/entities/Message.java +++ b/src/eu/siacs/conversations/entities/Message.java @@ -12,6 +12,7 @@ public class Message extends AbstractEntity { public static final String TABLENAME = "messages"; + public static final int STATUS_RECEPTION_FAILED = -3; public static final int STATUS_RECEIVED_OFFER = -2; public static final int STATUS_RECIEVING = -1; public static final int STATUS_RECIEVED = 0; diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index e234fd40..32a01460 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -232,6 +232,7 @@ public class XmppConnectionService extends Service { accountChangedListener.onAccountListChangedListener(); } if (account.getStatus() == Account.STATUS_ONLINE) { + mJingleConnectionManager.cancelInTransmission(); List conversations = getConversations(); for (int i = 0; i < conversations.size(); ++i) { if (conversations.get(i).getAccount() == account) { diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 59d8627e..0255fc04 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -252,6 +252,9 @@ public class ConversationFragment extends Fragment { info = getString(R.string.send_rejected); error = true; break; + case Message.STATUS_RECEPTION_FAILED: + info = getString(R.string.reception_failed); + error = true; default: if (multiReceived) { info = message.getCounterpart(); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 90d81b50..508fe95c 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -75,7 +75,7 @@ public class JingleConnection { } }; - final OnFileTransmitted onFileTransmitted = new OnFileTransmitted() { + final OnFileTransmissionStatusChanged onFileTransmissionSatusChanged = new OnFileTransmissionStatusChanged() { @Override public void onFileTransmitted(JingleFile file) { @@ -96,6 +96,11 @@ public class JingleConnection { } Log.d("xmppService","sucessfully transmitted file:"+file.getAbsolutePath()); } + + @Override + public void onFileTransferAborted() { + JingleConnection.this.cancel(); + } }; private OnProxyActivated onProxyActivated = new OnProxyActivated() { @@ -104,9 +109,9 @@ public class JingleConnection { public void success() { if (initiator.equals(account.getFullJid())) { Log.d("xmppService","we were initiating. sending file"); - transport.send(file,onFileTransmitted); + transport.send(file,onFileTransmissionSatusChanged); } else { - transport.receive(file,onFileTransmitted); + transport.receive(file,onFileTransmissionSatusChanged); Log.d("xmppService","we were responding. receiving file"); } } @@ -140,14 +145,14 @@ public class JingleConnection { Reason reason = packet.getReason(); if (reason!=null) { if (reason.hasChild("cancel")) { - this.receiveCancel(); + this.cancel(); } else if (reason.hasChild("success")) { this.receiveSuccess(); } else { - this.receiveCancel(); + this.cancel(); } } else { - this.receiveCancel(); + this.cancel(); } } else if (packet.isAction("session-accept")) { returnResult = receiveAccept(packet); @@ -279,13 +284,13 @@ public class JingleConnection { } this.file.setExpectedSize(size); } else { - this.sendCancel(); + this.cancel(); } } else { - this.sendCancel(); + this.cancel(); } } else { - this.sendCancel(); + this.cancel(); } } @@ -405,7 +410,7 @@ public class JingleConnection { connection.setActivated(true); } else { Log.d("xmppService","activated connection not found"); - this.sendCancel(); + this.cancel(); } } return true; @@ -479,10 +484,10 @@ public class JingleConnection { } else { if (initiator.equals(account.getFullJid())) { Log.d("xmppService","we were initiating. sending file"); - connection.send(file,onFileTransmitted); + connection.send(file,onFileTransmissionSatusChanged); } else { Log.d("xmppService","we were responding. receiving file"); - connection.receive(file,onFileTransmitted); + connection.receive(file,onFileTransmissionSatusChanged); } } } @@ -553,7 +558,7 @@ public class JingleConnection { } this.transportId = packet.getJingleContent().getTransportId(); this.transport = new JingleInbandTransport(this.account,this.responder,this.transportId,this.ibbBlockSize); - this.transport.receive(file, onFileTransmitted); + this.transport.receive(file, onFileTransmissionSatusChanged); JinglePacket answer = bootstrapPacket("transport-accept"); Content content = new Content("initiator", "a-file-offer"); content.setTransportId(this.transportId); @@ -582,7 +587,7 @@ public class JingleConnection { @Override public void established() { - JingleConnection.this.transport.send(file, onFileTransmitted); + JingleConnection.this.transport.send(file, onFileTransmissionSatusChanged); } }); return true; @@ -598,10 +603,21 @@ public class JingleConnection { this.mJingleConnectionManager.finishConnection(this); } - private void receiveCancel() { + void cancel() { + this.sendCancel(); this.disconnect(); + if (this.message!=null) { + if (this.responder.equals(account.getFullJid())) { + this.mXmppConnectionService.markMessage(this.message, Message.STATUS_RECEPTION_FAILED); + } else { + if (this.status == STATUS_INITIATED) { + this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_REJECTED); + } else { + this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_FAILED); + } + } + } this.status = STATUS_CANCELED; - this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_REJECTED); this.mJingleConnectionManager.finishConnection(this); } diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index a277b74c..d4af624a 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -155,4 +155,12 @@ public class JingleConnectionManager { Log.d("xmppService","no sid found in incomming ibb packet"); } } + + public void cancelInTransmission() { + for(JingleConnection connection : this.connections) { + if (connection.getStatus() == JingleConnection.STATUS_TRANSMITTING) { + connection.cancel(); + } + } + } } diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 7ecc5edf..b859e7c7 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -33,7 +33,7 @@ public class JingleInbandTransport extends JingleTransport { private long remainingSize; private MessageDigest digest; - private OnFileTransmitted onFileTransmitted; + private OnFileTransmissionStatusChanged onFileTransmissionStatusChanged; private OnIqPacketReceived onAckReceived = new OnIqPacketReceived() { @Override @@ -77,8 +77,8 @@ public class JingleInbandTransport extends JingleTransport { } @Override - public void receive(JingleFile file, OnFileTransmitted callback) { - this.onFileTransmitted = callback; + public void receive(JingleFile file, OnFileTransmissionStatusChanged callback) { + this.onFileTransmissionStatusChanged = callback; this.file = file; try { this.digest = MessageDigest.getInstance("SHA-1"); @@ -86,27 +86,35 @@ public class JingleInbandTransport extends JingleTransport { file.getParentFile().mkdirs(); file.createNewFile(); this.fileOutputStream = getOutputStream(file); + if (this.fileOutputStream==null) { + callback.onFileTransferAborted(); + return; + } this.remainingSize = file.getExpectedSize(); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + callback.onFileTransferAborted(); } catch (IOException e) { - e.printStackTrace(); + callback.onFileTransferAborted(); } } @Override - public void send(JingleFile file, OnFileTransmitted callback) { - this.onFileTransmitted = callback; + public void send(JingleFile file, OnFileTransmissionStatusChanged callback) { + this.onFileTransmissionStatusChanged = callback; this.file = file; try { this.digest = MessageDigest.getInstance("SHA-1"); this.digest.reset(); fileInputStream = this.getInputStream(file); + if (fileInputStream==null) { + callback.onFileTransferAborted(); + return; + } this.sendNextBlock(); } catch (FileNotFoundException e) { - e.printStackTrace(); + callback.onFileTransferAborted(); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + callback.onFileTransferAborted(); } } @@ -117,7 +125,7 @@ public class JingleInbandTransport extends JingleTransport { if (count == -1) { file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); fileInputStream.close(); - this.onFileTransmitted.onFileTransmitted(file); + this.onFileTransmissionStatusChanged.onFileTransmitted(file); } else { this.digest.update(buffer); String base64 = Base64.encodeToString(buffer, Base64.NO_WRAP); @@ -134,8 +142,7 @@ public class JingleInbandTransport extends JingleTransport { this.seq++; } } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + this.onFileTransmissionStatusChanged.onFileTransferAborted(); } } @@ -154,10 +161,10 @@ public class JingleInbandTransport extends JingleTransport { file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); fileOutputStream.flush(); fileOutputStream.close(); - this.onFileTransmitted.onFileTransmitted(file); + this.onFileTransmissionStatusChanged.onFileTransmitted(file); } } catch (IOException e) { - e.printStackTrace(); + this.onFileTransmissionStatusChanged.onFileTransferAborted(); } } diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index 7cdf1bc4..228827ab 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -10,7 +10,6 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; -import android.util.Log; import eu.siacs.conversations.utils.CryptoHelper; public class JingleSocks5Transport extends JingleTransport { @@ -84,7 +83,7 @@ public class JingleSocks5Transport extends JingleTransport { } - public void send(final JingleFile file, final OnFileTransmitted callback) { + public void send(final JingleFile file, final OnFileTransmissionStatusChanged callback) { new Thread(new Runnable() { @Override @@ -94,37 +93,34 @@ public class JingleSocks5Transport extends JingleTransport { MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.reset(); fileInputStream = getInputStream(file); + if (fileInputStream==null) { + callback.onFileTransferAborted(); + return; + } int count; - long txBytes = 0; byte[] buffer = new byte[8192]; while ((count = fileInputStream.read(buffer)) > 0) { - txBytes += count; outputStream.write(buffer, 0, count); digest.update(buffer, 0, count); } - Log.d("xmppService","txBytes="+txBytes); outputStream.flush(); file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); if (callback!=null) { callback.onFileTransmitted(file); } } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + callback.onFileTransferAborted(); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + callback.onFileTransferAborted(); } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + callback.onFileTransferAborted(); } finally { try { if (fileInputStream != null) { fileInputStream.close(); } } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + callback.onFileTransferAborted(); } } } @@ -132,7 +128,7 @@ public class JingleSocks5Transport extends JingleTransport { } - public void receive(final JingleFile file, final OnFileTransmitted callback) { + public void receive(final JingleFile file, final OnFileTransmissionStatusChanged callback) { new Thread(new Runnable() { @Override @@ -144,35 +140,34 @@ public class JingleSocks5Transport extends JingleTransport { file.getParentFile().mkdirs(); file.createNewFile(); OutputStream fileOutputStream = getOutputStream(file); + if (fileOutputStream==null) { + callback.onFileTransferAborted(); + return; + } long remainingSize = file.getExpectedSize(); byte[] buffer = new byte[8192]; int count = buffer.length; - long rxBytes = 0; while(remainingSize > 0) { count = inputStream.read(buffer); if (count==-1) { - Log.d("xmppService","read end"); + callback.onFileTransferAborted(); + return; } else { - rxBytes += count; fileOutputStream.write(buffer, 0, count); digest.update(buffer, 0, count); remainingSize-=count; } } - Log.d("xmppService","rx bytes="+rxBytes); fileOutputStream.flush(); fileOutputStream.close(); file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); callback.onFileTransmitted(file); } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + callback.onFileTransferAborted(); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + callback.onFileTransferAborted(); } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + callback.onFileTransferAborted(); } } }).start(); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java index 5db4b715..1acdfc39 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java @@ -19,8 +19,8 @@ import android.util.Log; public abstract class JingleTransport { public abstract void connect(final OnTransportConnected callback); - public abstract void receive(final JingleFile file, final OnFileTransmitted callback); - public abstract void send(final JingleFile file, final OnFileTransmitted callback); + public abstract void receive(final JingleFile file, final OnFileTransmissionStatusChanged callback); + public abstract void send(final JingleFile file, final OnFileTransmissionStatusChanged callback); private byte[] iv = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0xf}; protected InputStream getInputStream(JingleFile file) throws FileNotFoundException { diff --git a/src/eu/siacs/conversations/xmpp/jingle/OnFileTransmitted.java b/src/eu/siacs/conversations/xmpp/jingle/OnFileTransmissionStatusChanged.java similarity index 51% rename from src/eu/siacs/conversations/xmpp/jingle/OnFileTransmitted.java rename to src/eu/siacs/conversations/xmpp/jingle/OnFileTransmissionStatusChanged.java index fd5fd2f7..84f10417 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/OnFileTransmitted.java +++ b/src/eu/siacs/conversations/xmpp/jingle/OnFileTransmissionStatusChanged.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.xmpp.jingle; -public interface OnFileTransmitted { +public interface OnFileTransmissionStatusChanged { public void onFileTransmitted(JingleFile file); + public void onFileTransferAborted(); }