recreate http connection after restart. fixes stale download button. better failing

iNPUTmice created

Change summary

src/eu/siacs/conversations/http/HttpConnection.java        | 51 +++++--
src/eu/siacs/conversations/http/HttpConnectionManager.java | 14 +
src/eu/siacs/conversations/ui/ConversationActivity.java    |  5 
src/eu/siacs/conversations/ui/adapter/MessageAdapter.java  | 51 ++++++-
4 files changed, 95 insertions(+), 26 deletions(-)

Detailed changes

src/eu/siacs/conversations/http/HttpConnection.java 🔗

@@ -10,9 +10,7 @@ import java.net.URL;
 import javax.net.ssl.HttpsURLConnection;
 
 import android.graphics.BitmapFactory;
-import android.util.Log;
 
-import eu.siacs.conversations.Config;
 import eu.siacs.conversations.entities.Downloadable;
 import eu.siacs.conversations.entities.DownloadableFile;
 import eu.siacs.conversations.entities.Message;
@@ -26,6 +24,7 @@ public class HttpConnection implements Downloadable {
 	private URL mUrl;
 	private Message message;
 	private DownloadableFile file;
+	private long mPreviousFileSize = Long.MIN_VALUE;
 
 	public HttpConnection(HttpConnectionManager manager) {
 		this.mHttpConnectionManager = manager;
@@ -44,39 +43,60 @@ public class HttpConnection implements Downloadable {
 			mUrl = new URL(message.getBody());
 			this.file = mXmppConnectionService.getFileBackend().getConversationsFile(message,false);
 			message.setType(Message.TYPE_IMAGE);
-			mXmppConnectionService.markMessage(message, Message.STATUS_RECEIVED_CHECKING);
+			message.setStatus(Message.STATUS_RECEIVED_CHECKING);
+			mXmppConnectionService.updateConversationUi();
 			checkFileSize();
 		} catch (MalformedURLException e) {
 			this.cancel();
 		}
 	}
 	
+	public void init(Message message, URL url) {
+		this.message = message;
+		this.message.setDownloadable(this);
+		this.mUrl = url;
+		this.file = mXmppConnectionService.getFileBackend().getConversationsFile(message,false);
+		this.mPreviousFileSize = message.getImageParams().size;
+		message.setType(Message.TYPE_IMAGE);
+		message.setStatus(Message.STATUS_RECEIVED_CHECKING);
+		mXmppConnectionService.updateConversationUi();
+		checkFileSize();
+	}
+	
 	private void checkFileSize() {
 		new Thread(new FileSizeChecker()).start();
 	}
 
 	public void cancel() {
 		mXmppConnectionService.markMessage(message, Message.STATUS_RECEPTION_FAILED);
-		Log.d(Config.LOGTAG,"canceled download");
+		mHttpConnectionManager.finishConnection(this);
+	}
+	
+	private void finish() {
+		message.setStatus(Message.STATUS_RECEIVED);
+		mXmppConnectionService.updateMessage(message);
+		mHttpConnectionManager.finishConnection(this);
 	}
 
 	private class FileSizeChecker implements Runnable {
 
 		@Override
 		public void run() {
+			long size;
 			try {
-				long size = retrieveFileSize();
-				file.setExpectedSize(size);
-				message.setBody(mUrl.toString()+","+String.valueOf(size));
-				if (size <= mHttpConnectionManager.getAutoAcceptFileSize()) {
-					mXmppConnectionService.updateMessage(message);
-					start();
-				} else {
-					message.setStatus(Message.STATUS_RECEIVED_OFFER);
-					mXmppConnectionService.updateMessage(message);
-				}
+				size = retrieveFileSize();
 			} catch (IOException e) {
 				cancel();
+				return;
+			}
+			file.setExpectedSize(size);
+			message.setBody(mUrl.toString()+","+String.valueOf(size));
+			if (size <= mHttpConnectionManager.getAutoAcceptFileSize() || size == mPreviousFileSize) {
+				mXmppConnectionService.updateMessage(message);
+				start();
+			} else {
+				message.setStatus(Message.STATUS_RECEIVED_OFFER);
+				mXmppConnectionService.updateMessage(message);
 			}
 		}
 
@@ -107,8 +127,7 @@ public class HttpConnection implements Downloadable {
 				mXmppConnectionService.markMessage(message, Message.STATUS_RECEIVING);
 				download();
 				updateImageBounds();
-				message.setStatus(Message.STATUS_RECEIVED);
-				mXmppConnectionService.updateMessage(message);
+				finish();
 			} catch (IOException e) {
 				cancel();
 			}

src/eu/siacs/conversations/http/HttpConnectionManager.java 🔗

@@ -1,5 +1,6 @@
 package eu.siacs.conversations.http;
 
+import java.net.URL;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -12,8 +13,6 @@ public class HttpConnectionManager extends AbstractConnectionManager {
 	public HttpConnectionManager(XmppConnectionService service) {
 		super(service);
 	}
-
-	private XmppConnectionService mXmppConnectionService;
 	
 	private List<HttpConnection> connections = new CopyOnWriteArrayList<HttpConnection>();
 	
@@ -24,4 +23,15 @@ public class HttpConnectionManager extends AbstractConnectionManager {
 		this.connections.add(connection);
 		return connection;
 	}
+	
+	public HttpConnection createNewConnection(Message message, URL url) {
+		HttpConnection connection = new HttpConnection(this);
+		connection.init(message,url);
+		this.connections.add(connection);
+		return connection;
+	}
+	
+	public void finishConnection(HttpConnection connection) {
+		this.connections.remove(connection);
+	}
 }

src/eu/siacs/conversations/ui/ConversationActivity.java 🔗

@@ -1,12 +1,17 @@
 package eu.siacs.conversations.ui;
 
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 
 import eu.siacs.conversations.R;
 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.Message.ImageParams;
 import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate;
 import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;

src/eu/siacs/conversations/ui/adapter/MessageAdapter.java 🔗

@@ -1,5 +1,7 @@
 package eu.siacs.conversations.ui.adapter;
 
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.HashMap;
 import java.util.List;
 
@@ -225,10 +227,19 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 		viewHolder.messageBody.setVisibility(View.VISIBLE);
 		if (message.getBody() != null) {
 			if (message.getType() != Message.TYPE_PRIVATE) {
-				String body = Config.PARSE_EMOTICONS ? UIHelper
-						.transformAsciiEmoticons(message.getMergedBody())
-						: message.getMergedBody();
-				viewHolder.messageBody.setText(body);
+				if (message.getType() == Message.TYPE_IMAGE) {
+					String orign = message.getImageParams().origin;
+					if (orign!=null) {
+						viewHolder.messageBody.setText(orign);
+					} else {
+						viewHolder.messageBody.setText(message.getBody());
+					}
+				} else {
+					String body = Config.PARSE_EMOTICONS ? UIHelper
+							.transformAsciiEmoticons(message.getMergedBody())
+							: message.getMergedBody();
+					viewHolder.messageBody.setText(body);
+				}
 			} else {
 				String privateMarker;
 				if (message.getStatus() <= Message.STATUS_RECEIVED) {
@@ -474,6 +485,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 				displayInfoMessage(viewHolder, R.string.receiving_image);
 			} else if (item.getStatus() == Message.STATUS_RECEIVED_CHECKING) {
 				displayInfoMessage(viewHolder, R.string.checking_image);
+			} else if (item.getStatus() == Message.STATUS_RECEPTION_FAILED) {
+				displayTextMessage(viewHolder, item);
 			} else if (item.getStatus() == Message.STATUS_RECEIVED_OFFER) {
 				viewHolder.image.setVisibility(View.GONE);
 				viewHolder.messageBody.setVisibility(View.GONE);
@@ -483,10 +496,10 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 
 							@Override
 							public void onClick(View v) {
-								Downloadable downloadable = item
-										.getDownloadable();
-								if (downloadable != null) {
-									downloadable.start();
+								if (!startDonwloadable(item)) {
+									activity.xmppConnectionService.markMessage(
+											item,
+											Message.STATUS_RECEPTION_FAILED);
 								}
 							}
 						});
@@ -527,6 +540,28 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 		return view;
 	}
 
+	public boolean startDonwloadable(Message message) {
+		Downloadable downloadable = message.getDownloadable();
+		if (downloadable != null) {
+			downloadable.start();
+			return true;
+		} else {
+			ImageParams params = message.getImageParams();
+			if (params.origin != null) {
+				try {
+					URL url = new URL(params.origin);
+					activity.xmppConnectionService.getHttpConnectionManager()
+							.createNewConnection(message, url);
+					return true;
+				} catch (MalformedURLException e) {
+					return false;
+				}
+			} else {
+				return false;
+			}
+		}
+	}
+
 	private static class ViewHolder {
 
 		protected LinearLayout message_box;