HttpConnection.java

  1package eu.siacs.conversations.http;
  2
  3import java.io.BufferedInputStream;
  4import java.io.IOException;
  5import java.io.OutputStream;
  6import java.net.HttpURLConnection;
  7import java.net.MalformedURLException;
  8import java.net.URL;
  9
 10import javax.net.ssl.HttpsURLConnection;
 11
 12import android.content.Intent;
 13import android.graphics.BitmapFactory;
 14import android.net.Uri;
 15
 16import eu.siacs.conversations.entities.Downloadable;
 17import eu.siacs.conversations.entities.DownloadableFile;
 18import eu.siacs.conversations.entities.Message;
 19import eu.siacs.conversations.services.XmppConnectionService;
 20
 21public class HttpConnection implements Downloadable {
 22
 23	private HttpConnectionManager mHttpConnectionManager;
 24	private XmppConnectionService mXmppConnectionService;
 25
 26	private URL mUrl;
 27	private Message message;
 28	private DownloadableFile file;
 29	private int mStatus = Downloadable.STATUS_UNKNOWN;
 30	private boolean mAutostart = true;
 31
 32	public HttpConnection(HttpConnectionManager manager) {
 33		this.mHttpConnectionManager = manager;
 34		this.mXmppConnectionService = manager.getXmppConnectionService();
 35	}
 36
 37	@Override
 38	public void start() {
 39		changeStatus(STATUS_DOWNLOADING);
 40		new Thread(new FileDownloader()).start();
 41	}
 42
 43	public void init(Message message) {
 44		this.message = message;
 45		this.message.setDownloadable(this);
 46		try {
 47			mUrl = new URL(message.getBody());
 48			this.file = mXmppConnectionService.getFileBackend()
 49					.getFile(message, false);
 50			this.mAutostart = true;
 51			checkFileSize();
 52		} catch (MalformedURLException e) {
 53			this.cancel();
 54		}
 55	}
 56
 57	private void checkFileSize() {
 58		changeStatus(STATUS_CHECKING);
 59		new Thread(new FileSizeChecker()).start();
 60	}
 61
 62	public void cancel() {
 63		mHttpConnectionManager.finishConnection(this);
 64		message.setDownloadable(null);
 65		message.setBody(mUrl.toString());
 66		mXmppConnectionService.updateMessage(message);
 67	}
 68
 69	private void finish() {
 70		Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
 71		intent.setData(Uri.fromFile(file));
 72		mXmppConnectionService.sendBroadcast(intent);
 73		message.setDownloadable(null);
 74		mHttpConnectionManager.finishConnection(this);
 75	}
 76
 77	private void changeStatus(int status) {
 78		this.mStatus = status;
 79		mXmppConnectionService.updateConversationUi();
 80	}
 81
 82	private class FileSizeChecker implements Runnable {
 83
 84		@Override
 85		public void run() {
 86			long size;
 87			try {
 88				size = retrieveFileSize();
 89			} catch (IOException e) {
 90				cancel();
 91				return;
 92			}
 93			file.setExpectedSize(size);
 94			message.setType(Message.TYPE_IMAGE);
 95			if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) {
 96				start();
 97			} else {
 98				changeStatus(STATUS_OFFER);
 99			}
100		}
101
102		private long retrieveFileSize() throws IOException {
103			HttpURLConnection connection = (HttpURLConnection) mUrl
104					.openConnection();
105			connection.setRequestMethod("HEAD");
106			if (connection instanceof HttpsURLConnection) {
107
108			}
109			String contentLength = connection.getHeaderField("Content-Length");
110			if (contentLength == null) {
111				throw new IOException();
112			}
113			try {
114				return Long.parseLong(contentLength, 10);
115			} catch (NumberFormatException e) {
116				throw new IOException();
117			}
118		}
119
120	}
121
122	private class FileDownloader implements Runnable {
123
124		@Override
125		public void run() {
126			try {
127				download();
128				updateImageBounds();
129				finish();
130			} catch (IOException e) {
131				cancel();
132			}
133		}
134
135		private void download() throws IOException {
136			HttpURLConnection connection = (HttpURLConnection) mUrl
137					.openConnection();
138			if (connection instanceof HttpsURLConnection) {
139
140			}
141			BufferedInputStream is = new BufferedInputStream(
142					connection.getInputStream());
143			OutputStream os = file.createOutputStream();
144			int count = -1;
145			byte[] buffer = new byte[1024];
146			while ((count = is.read(buffer)) != -1) {
147				os.write(buffer, 0, count);
148			}
149			os.flush();
150			os.close();
151			is.close();
152		}
153
154		private void updateImageBounds() {
155			BitmapFactory.Options options = new BitmapFactory.Options();
156			options.inJustDecodeBounds = true;
157			BitmapFactory.decodeFile(file.getAbsolutePath(), options);
158			int imageHeight = options.outHeight;
159			int imageWidth = options.outWidth;
160			message.setBody(mUrl.toString() + "," + file.getSize() + ','
161					+ imageWidth + ',' + imageHeight);
162			mXmppConnectionService.updateMessage(message);
163		}
164
165	}
166
167	@Override
168	public int getStatus() {
169		return this.mStatus;
170	}
171
172	@Override
173	public long getFileSize() {
174		if (this.file != null) {
175			return this.file.getExpectedSize();
176		} else {
177			return 0;
178		}
179	}
180}