mtm support for image downloader

iNPUTmice created

Change summary

.gitmodules                                                    |  2 
libs/MemorizingTrustManager                                    |  2 
res/values/strings.xml                                         |  1 
src/eu/siacs/conversations/entities/Downloadable.java          |  1 
src/eu/siacs/conversations/http/HttpConnection.java            | 62 +++
src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java |  2 
src/eu/siacs/conversations/ui/adapter/MessageAdapter.java      |  7 
7 files changed, 60 insertions(+), 17 deletions(-)

Detailed changes

.gitmodules 🔗

@@ -7,4 +7,4 @@
 	url = https://github.com/open-keychain/openpgp-api-lib.git
 [submodule "libs/MemorizingTrustManager"]
 	path = libs/MemorizingTrustManager
-	url = https://github.com/ge0rg/MemorizingTrustManager
+	url = https://github.com/iNPUTmice/MemorizingTrustManager.git

libs/MemorizingTrustManager 🔗

@@ -1 +1 @@
-Subproject commit 3f67eba2e4663841dd0024908f8ffb2613078140
+Subproject commit fad835037adc1bd313bb56b694426fca4eb67346

res/values/strings.xml 🔗

@@ -269,5 +269,6 @@
     <string name="checking_image">Checking image on HTTP host</string>
     <string name="image_file_deleted">The image file has been deleted</string>
     <string name="not_connected_try_again">You are not connected. Try again later</string>
+    <string name="check_image_filesize">Check image file size</string>
 
 </resources>

src/eu/siacs/conversations/entities/Downloadable.java 🔗

@@ -11,6 +11,7 @@ public interface Downloadable {
 	public static final int STATUS_OFFER = 0x203;
 	public static final int STATUS_DOWNLOADING = 0x204;
 	public static final int STATUS_DELETED = 0x205;
+	public static final int STATUS_OFFER_CHECK_FILESIZE = 0x206;
 
 	public boolean start();
 

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

@@ -6,15 +6,18 @@ import java.io.OutputStream;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
 
 import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.X509TrustManager;
 
 import android.content.Intent;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
-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;
@@ -39,8 +42,12 @@ public class HttpConnection implements Downloadable {
 	@Override
 	public boolean start() {
 		if (mXmppConnectionService.hasInternetConnection()) {
-			changeStatus(STATUS_DOWNLOADING);
-			new Thread(new FileDownloader()).start();
+			if (this.mStatus == STATUS_OFFER_CHECK_FILESIZE) {
+				checkFileSize(true);
+			} else {
+				changeStatus(STATUS_DOWNLOADING);
+				new Thread(new FileDownloader()).start();
+			}
 			return true;
 		} else {
 			return false;
@@ -52,18 +59,18 @@ public class HttpConnection implements Downloadable {
 		this.message.setDownloadable(this);
 		try {
 			mUrl = new URL(message.getBody());
-			this.file = mXmppConnectionService.getFileBackend()
-					.getFile(message, false);
+			this.file = mXmppConnectionService.getFileBackend().getFile(
+					message, false);
 			this.mAutostart = true;
-			checkFileSize();
+			checkFileSize(false);
 		} catch (MalformedURLException e) {
 			this.cancel();
 		}
 	}
 
-	private void checkFileSize() {
+	private void checkFileSize(boolean interactive) {
 		changeStatus(STATUS_CHECKING);
-		new Thread(new FileSizeChecker()).start();
+		new Thread(new FileSizeChecker(interactive)).start();
 	}
 
 	public void cancel() {
@@ -84,33 +91,62 @@ public class HttpConnection implements Downloadable {
 		this.mStatus = status;
 		mXmppConnectionService.updateConversationUi();
 	}
+	
+	private void setupTrustManager(HttpsURLConnection connection, boolean interactive) {
+		X509TrustManager trustManager;
+		if (interactive) {
+			trustManager = mXmppConnectionService.getMemorizingTrustManager();
+		} else {
+			trustManager = mXmppConnectionService.getMemorizingTrustManager().getNonInteractive();
+		}
+		try {
+			SSLContext sc = SSLContext.getInstance("TLS");
+			sc.init(null,new X509TrustManager[] { trustManager },mXmppConnectionService.getRNG());
+			connection.setSSLSocketFactory(sc.getSocketFactory());
+		} catch (KeyManagementException e) {
+			return;
+		} catch (NoSuchAlgorithmException e) {
+			return;
+		}
+	}
 
 	private class FileSizeChecker implements Runnable {
+		
+		private boolean interactive = false;
+
+		public FileSizeChecker(boolean interactive) {
+			this.interactive = interactive;
+		}
 
 		@Override
 		public void run() {
 			long size;
 			try {
 				size = retrieveFileSize();
+			} catch (SSLHandshakeException e) {
+				changeStatus(STATUS_OFFER_CHECK_FILESIZE);
+				return;
 			} catch (IOException e) {
 				cancel();
 				return;
 			}
 			file.setExpectedSize(size);
-			if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) {
+			if (size <= mHttpConnectionManager.getAutoAcceptFileSize()
+					&& mAutostart) {
 				start();
 			} else {
 				changeStatus(STATUS_OFFER);
 			}
 		}
 
-		private long retrieveFileSize() throws IOException {
+		private long retrieveFileSize() throws IOException, SSLHandshakeException {
 			HttpURLConnection connection = (HttpURLConnection) mUrl
 					.openConnection();
 			connection.setRequestMethod("HEAD");
 			if (connection instanceof HttpsURLConnection) {
-
+				setupTrustManager((HttpsURLConnection) connection, interactive);
 			}
+			connection.connect();
 			String contentLength = connection.getHeaderField("Content-Length");
 			if (contentLength == null) {
 				throw new IOException();
@@ -141,7 +177,7 @@ public class HttpConnection implements Downloadable {
 			HttpURLConnection connection = (HttpURLConnection) mUrl
 					.openConnection();
 			if (connection instanceof HttpsURLConnection) {
-
+				setupTrustManager((HttpsURLConnection) connection, true);
 			}
 			BufferedInputStream is = new BufferedInputStream(
 					connection.getInputStream());

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

@@ -92,6 +92,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
 					mLastMessage.setText(R.string.receiving_image);
 				} else if (d.getStatus() == Downloadable.STATUS_OFFER) {
 					mLastMessage.setText(R.string.image_offered_for_download);
+				} else if (d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) {
+					mLastMessage.setText(R.string.image_offered_for_download);
 				} else if (d.getStatus() == Downloadable.STATUS_DELETED) {
 					mLastMessage.setText(R.string.image_file_deleted);
 				} else {

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

@@ -264,10 +264,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 	}
 
 	private void displayDownloadableMessage(ViewHolder viewHolder,
-			final Message message) {
+			final Message message, int resid) {
 		viewHolder.image.setVisibility(View.GONE);
 		viewHolder.messageBody.setVisibility(View.GONE);
 		viewHolder.download_button.setVisibility(View.VISIBLE);
+		viewHolder.download_button.setText(resid);
 		viewHolder.download_button.setOnClickListener(new OnClickListener() {
 
 			@Override
@@ -493,7 +494,9 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 					&& d.getStatus() == Downloadable.STATUS_DELETED) {
 				displayInfoMessage(viewHolder, R.string.image_file_deleted);
 			} else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER) {
-				displayDownloadableMessage(viewHolder, item);
+				displayDownloadableMessage(viewHolder, item,R.string.download_image);
+			} else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) {
+				displayDownloadableMessage(viewHolder, item,R.string.check_image_filesize);
 			} else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED)
 					|| (item.getEncryption() == Message.ENCRYPTION_NONE)
 					|| (item.getEncryption() == Message.ENCRYPTION_OTR)) {