From 62bc6885db07423a434f945de9def863cb12b8c1 Mon Sep 17 00:00:00 2001 From: steckbrief Date: Fri, 16 Feb 2018 21:04:29 +0100 Subject: introduces cancel status for file transfers, fixes NPE in file sharing after picture resize --- .../conversationsplus/entities/Message.java | 1 + .../conversationsplus/entities/Transferable.java | 2 ++ .../entities/TransferablePlaceholder.java | 5 ++++ .../conversationsplus/parser/MessageParser.java | 2 +- .../services/XmppConnectionService.java | 3 ++- .../services/filetransfer/FileTransferManager.java | 2 +- .../http/download/HttpFileDownloadCallback.java | 1 + .../http/download/HttpRetrieveHead.java | 2 +- .../conversationsplus/ui/ConversationFragment.java | 5 ++-- .../ui/adapter/MessageAdapter.java | 28 +++++++++++++++------- .../ResizePictureUserDecisionListener.java | 5 +++- .../conversationsplus/utils/ConversationUtil.java | 4 ++++ .../conversationsplus/utils/MessageUtil.java | 5 ++++ .../xmpp/jingle/JingleConnection.java | 6 +++++ src/main/res/values/strings.xml | 1 + 15 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java b/src/main/java/de/thedevstack/conversationsplus/entities/Message.java index b8ebfe2b..36ab036e 100644 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java +++ b/src/main/java/de/thedevstack/conversationsplus/entities/Message.java @@ -27,6 +27,7 @@ public class Message extends AbstractEntity implements LoadAvatarFor { public static final int STATUS_OFFERED = 6; public static final int STATUS_SEND_RECEIVED = 7; public static final int STATUS_SEND_DISPLAYED = 8; + public static final int STATUS_SEND_CANCELED = 9; // FIXME This bullshit is needed until status is handled more properly public static final int ENCRYPTION_NONE = 0; public static final int ENCRYPTION_PGP = 1; diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Transferable.java b/src/main/java/de/thedevstack/conversationsplus/entities/Transferable.java index 10bc8bcf..95472548 100644 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Transferable.java +++ b/src/main/java/de/thedevstack/conversationsplus/entities/Transferable.java @@ -28,4 +28,6 @@ public interface Transferable { int getProgress(); void cancel(); + + boolean isCanceled(); } diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/TransferablePlaceholder.java b/src/main/java/de/thedevstack/conversationsplus/entities/TransferablePlaceholder.java index 40292e1f..56d8564e 100644 --- a/src/main/java/de/thedevstack/conversationsplus/entities/TransferablePlaceholder.java +++ b/src/main/java/de/thedevstack/conversationsplus/entities/TransferablePlaceholder.java @@ -26,4 +26,9 @@ public class TransferablePlaceholder implements Transferable { public void cancel() { } + + @Override + public boolean isCanceled() { + return false; + } } diff --git a/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java b/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java index 4cc6f8b2..889adbac 100644 --- a/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java +++ b/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java @@ -490,7 +490,7 @@ public class MessageParser extends AbstractParser implements if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && ConversationsPlusPreferences.autoAcceptFileSize() > 0 - && (message.isHttpUploaded() || ConversationsPlusPreferences.autoDownloadFileLink())) { + && (message.isHttpUploaded() || MessageUtil.hasDownloadableLink(message))) { // Can this be checked by MessageUtil.needsDownload(message) ?? HttpRetrieveHead hrh = new HttpRetrieveHead(message); hrh.setListener(new AutomaticFileDownload(true)); hrh.retrieveAndSetContentTypeAndLength(); diff --git a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java index 963adfe4..bad0415f 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java @@ -2415,7 +2415,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void resendFailedMessages(final Message message) { - if (message.getStatus() == Message.STATUS_SEND_FAILED) { + if (message.getStatus() == Message.STATUS_SEND_FAILED + || message.getStatus() == Message.STATUS_SEND_CANCELED) { message.setTime(System.currentTimeMillis()); MessageUtil.markMessage(message, Message.STATUS_WAITING); this.resendMessage(message, false); diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java index b99f8d82..63f1547f 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java @@ -134,7 +134,7 @@ public class FileTransferManager implements FileTransferStatusListener { @Override public void onCancel(FileTransferEntity entity) { this.activeTransfers.remove(entity.getMessage().getUuid()); - MessageUtil.markMessage(entity.getMessage(), Message.STATUS_SEND_FAILED); // TODO New Status CANCELED! + MessageUtil.markMessage(entity.getMessage(), Message.STATUS_SEND_CANCELED); } @Override diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/download/HttpFileDownloadCallback.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/download/HttpFileDownloadCallback.java index 2c31754c..18c13a3f 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/download/HttpFileDownloadCallback.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/download/HttpFileDownloadCallback.java @@ -41,6 +41,7 @@ public class HttpFileDownloadCallback implements Callback { StreamUtil.close(os); FileBackend.updateMediaScanner(file, XmppConnectionServiceAccessor.xmppConnectionService); this.entity.transferred(); + MessageUtil.updateFileParams(this.entity.getMessage()); changeStatus(FileStatus.DOWNLOADED); } else { Logging.e("http-download", "Failed to retrieve file from remote host. HTTP response: " + response.code() + ", " + response.body().string()); diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/download/HttpRetrieveHead.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/download/HttpRetrieveHead.java index 8d23d9c0..1313bcca 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/download/HttpRetrieveHead.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/download/HttpRetrieveHead.java @@ -41,7 +41,7 @@ public class HttpRetrieveHead implements Http, Callback { if (null == this.url) { message.setTreatAsDownloadable(Message.Decision.NEVER); // TODO find sth better if (null != message.getFileParams()) { - MessageUtil.setAndSaveFileStatus(message, FileStatus.NOT_FOUND); + MessageUtil.setAndSaveFileStatus(message, FileStatus.UNDEFINED); } } } diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java index d25fa461..528e2a55 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java @@ -553,7 +553,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (treatAsFile || (GeoHelper.isGeoUri(m.getBody()))) { shareWith.setVisible(true); } - if (m.getStatus() == Message.STATUS_SEND_FAILED) { + if (m.getStatus() == Message.STATUS_SEND_FAILED + || Message.STATUS_SEND_CANCELED == m.getStatus()) { sendAgain.setVisible(true); } if (m.hasFileOnRemoteHost() @@ -700,7 +701,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (transferable != null) { transferable.cancel(); } else { - MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED); + MessageUtil.markMessage(message, Message.STATUS_SEND_CANCELED); } } diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java index 0b544581..96b5954e 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java @@ -49,6 +49,7 @@ import de.thedevstack.conversationsplus.persistance.FileBackend; import de.thedevstack.conversationsplus.providers.ConversationsPlusFileProvider; import de.thedevstack.conversationsplus.services.avatar.AvatarCache; import de.thedevstack.conversationsplus.services.avatar.AvatarService; +import de.thedevstack.conversationsplus.services.filetransfer.FileTransferStatusEnum; import de.thedevstack.conversationsplus.services.filetransfer.http.download.AutomaticFileDownload; import de.thedevstack.conversationsplus.ui.ConversationActivity; import de.thedevstack.conversationsplus.utils.CryptoHelper; @@ -182,6 +183,10 @@ public class MessageAdapter extends ArrayAdapter { info = getContext().getString(R.string.send_failed); error = true; break; + case Message.STATUS_SEND_CANCELED: + info = getContext().getString(R.string.send_canceled); + error = true; + break; default: if (multiReceived) { info = UIHelper.getMessageDisplayName(message); @@ -251,7 +256,7 @@ public class MessageAdapter extends ArrayAdapter { if (message.hasFileAttached() && null != message.getFileParams() && null != viewHolder.remoteFileStatus) { FileStatus fileStatus = message.getFileParams().getFileStatus(); if (fileStatus == FileStatus.DELETE_FAILED || fileStatus == FileStatus.DELETED || fileStatus == FileStatus.DELETING || fileStatus == FileStatus.NOT_FOUND) { - viewHolder.remoteFileStatus.setVisibility(View.VISIBLE); + TextViewUtil.visible(viewHolder.remoteFileStatus); switch (fileStatus) { case DELETE_FAILED: TextViewUtil.setColor(viewHolder.remoteFileStatus, R.color.error); @@ -268,6 +273,8 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_not_found); break; } + } else { + TextViewUtil.gone(viewHolder.remoteFileStatus); } } } @@ -527,19 +534,22 @@ public class MessageAdapter extends ArrayAdapter { if (FileStatus.CHECKING_FILE_SIZE == message.getFileParams().getFileStatus()) { displayInfoMessage(viewHolder, activity.getString(R.string.checking_remote_filesize)); } else if (MessageUtil.isAttachedFileAnImage(message) - && (FileStatus.DOWNLOADED == message.getFileParams().getFileStatus()) - || FileStatus.DELETED == message.getFileParams().getFileStatus() - || FileStatus.DELETING == message.getFileParams().getFileStatus() - || FileStatus.DELETE_FAILED == message.getFileParams().getFileStatus() - || FileStatus.UPLOADED == message.getFileParams().getFileStatus()) { + && (FileStatus.DOWNLOADED == message.getFileParams().getFileStatus() + || FileStatus.DELETED == message.getFileParams().getFileStatus() + || FileStatus.DELETING == message.getFileParams().getFileStatus() + || FileStatus.DELETE_FAILED == message.getFileParams().getFileStatus() + || FileStatus.NEEDS_UPLOAD == message.getFileParams().getFileStatus() + || FileStatus.UPLOADED == message.getFileParams().getFileStatus() + || FileStatus.UPLOAD_FAILED == message.getFileParams().getFileStatus() + || (null != transferable + && (transferable.isCanceled() + || Transferable.STATUS_UPLOADING == transferable.getStatus())))) { displayImageMessage(viewHolder, message); } else if ((MessageUtil.isTypeFileAndDecrypted(message) || FileStatus.DOWNLOADED == message.getFileParams().getFileStatus()) && !MessageUtil.needsDownload(message)) { displayOpenableMessage(viewHolder, message); } else if (Message.Decision.NEVER == message.treatAsDownloadable() || !MessageUtil.mayFileRemoteAvailable(message)) { displayTextMessage(viewHolder, message); - } else if (FileStatus.UPLOAD_FAILED == message.getFileParams().getFileStatus()) { - displayImageMessage(viewHolder, message); // TODO Show failed status } else if (null != transferable) { switch (transferable.getStatus()) { case Transferable.STATUS_OFFER: @@ -648,7 +658,7 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.contact_picture = ViewUtil.visible(view, R.id.message_photo); viewHolder.status_message = TextViewUtil.visible(view, R.id.status_message); } - if (SENT == type) { + if (SENT == type) { // This field is only useful for sent messages -> because of deletion of own files -> maybe a use case for recvd possible viewHolder.remoteFileStatus = TextViewUtil.gone(view, R.id.remote_file_status); } view.setTag(viewHolder); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java index 68d2e47c..e6ec7496 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java @@ -119,7 +119,10 @@ public class ResizePictureUserDecisionListener implements UserDecisionListener { } else { message = new Message(conversation, "", conversation.getNextEncryption()); } - message.setCounterpart(conversation.getNextCounterpart()); + if (null != conversation.getNextCounterpart() && null == message.getCounterpart()) { + message.setCounterpart(conversation.getNextCounterpart()); + } + //message.setType(Message.TYPE_IMAGE); message.setFileParams(new FileParams()); message.getFileParams().setFileStatus(FileStatus.NEEDS_UPLOAD); diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java index 55fd1b8e..709b3f20 100644 --- a/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java +++ b/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java @@ -5,6 +5,7 @@ import android.net.Uri; import de.thedevstack.conversationsplus.ConversationsPlusApplication; import de.thedevstack.conversationsplus.crypto.PgpEngine; import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.entities.FileParams; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.enums.FileStatus; import de.thedevstack.conversationsplus.exceptions.FileCopyException; @@ -45,6 +46,9 @@ public class ConversationUtil { } message.setCounterpart(conversation.getNextCounterpart()); //message.setType(Message.TYPE_FILE); + if (null == message.getFileParams()) { + message.setFileParams(new FileParams()); + } message.getFileParams().setFileStatus(FileStatus.NEEDS_UPLOAD); String path = FileUtils.getPath(uri); if (path != null) { diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java index fa403cc5..2e346486 100644 --- a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java +++ b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java @@ -50,6 +50,7 @@ public final class MessageUtil { URL url = new URL(body); if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { message.setTreatAsDownloadable(Message.Decision.NEVER); + fileParams.setFileStatus(FileStatus.UNDEFINED); return; } String extension = FileUtils.getRelevantExtension(url); @@ -69,6 +70,7 @@ public final class MessageUtil { if (extension == null) { message.setTreatAsDownloadable(Message.Decision.NEVER); + fileParams.setFileStatus(FileStatus.UNDEFINED); return; } byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url); @@ -79,12 +81,14 @@ public final class MessageUtil { fileParams.setKeyAndIv(ivAndKey); } else { message.setTreatAsDownloadable(Message.Decision.NEVER); + fileParams.setFileStatus(FileStatus.UNDEFINED); } } else if (Transferable.VALID_IMAGE_EXTENSIONS.contains(extension) || Transferable.WELL_KNOWN_EXTENSIONS.contains(extension)) { message.setTreatAsDownloadable(Message.Decision.SHOULD); } else { message.setTreatAsDownloadable(Message.Decision.NEVER); + fileParams.setFileStatus(FileStatus.UNDEFINED); } if (message.treatAsDownloadable() == Message.Decision.MUST @@ -94,6 +98,7 @@ public final class MessageUtil { } } catch (MalformedURLException e) { message.setTreatAsDownloadable(Message.Decision.NEVER); + fileParams.setFileStatus(FileStatus.UNDEFINED); } } diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java index ea93fdb8..49a10684 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java @@ -57,6 +57,7 @@ public class JingleConnection implements Transferable { private int mJingleStatus = -1; private int mStatus = Transferable.STATUS_UNKNOWN; + private boolean canceled; private Message message; private String sessionId; private Account account; @@ -834,6 +835,7 @@ public class JingleConnection implements Transferable { } private void sendCancel() { + this.canceled = true; JinglePacket packet = bootstrapPacket("session-terminate"); Reason reason = new Reason(); reason.addChild("cancel"); @@ -1018,6 +1020,10 @@ public class JingleConnection implements Transferable { } } + public boolean isCanceled() { + return this.canceled; + } + @Override public int getProgress() { return this.mProgress; diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 0ab2c02c..8e9a1dee 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -699,4 +699,5 @@ Send client information Sends information about your android version Send your android version + delivery canceled -- cgit v1.2.3