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		mXmppConnectionService.updateConversationUi();
 66	}
 67
 68	private void finish() {
 69		Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
 70		intent.setData(Uri.fromFile(file));
 71		mXmppConnectionService.sendBroadcast(intent);
 72		message.setDownloadable(null);
 73		mHttpConnectionManager.finishConnection(this);
 74	}
 75
 76	private void changeStatus(int status) {
 77		this.mStatus = status;
 78		mXmppConnectionService.updateConversationUi();
 79	}
 80
 81	private class FileSizeChecker implements Runnable {
 82
 83		@Override
 84		public void run() {
 85			long size;
 86			try {
 87				size = retrieveFileSize();
 88			} catch (IOException e) {
 89				cancel();
 90				return;
 91			}
 92			file.setExpectedSize(size);
 93			if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) {
 94				start();
 95			} else {
 96				changeStatus(STATUS_OFFER);
 97			}
 98		}
 99
100		private long retrieveFileSize() throws IOException {
101			HttpURLConnection connection = (HttpURLConnection) mUrl
102					.openConnection();
103			connection.setRequestMethod("HEAD");
104			if (connection instanceof HttpsURLConnection) {
105
106			}
107			String contentLength = connection.getHeaderField("Content-Length");
108			if (contentLength == null) {
109				throw new IOException();
110			}
111			try {
112				return Long.parseLong(contentLength, 10);
113			} catch (NumberFormatException e) {
114				throw new IOException();
115			}
116		}
117
118	}
119
120	private class FileDownloader implements Runnable {
121
122		@Override
123		public void run() {
124			try {
125				download();
126				updateImageBounds();
127				finish();
128			} catch (IOException e) {
129				cancel();
130			}
131		}
132
133		private void download() throws IOException {
134			HttpURLConnection connection = (HttpURLConnection) mUrl
135					.openConnection();
136			if (connection instanceof HttpsURLConnection) {
137
138			}
139			BufferedInputStream is = new BufferedInputStream(
140					connection.getInputStream());
141			OutputStream os = file.createOutputStream();
142			int count = -1;
143			byte[] buffer = new byte[1024];
144			while ((count = is.read(buffer)) != -1) {
145				os.write(buffer, 0, count);
146			}
147			os.flush();
148			os.close();
149			is.close();
150		}
151
152		private void updateImageBounds() {
153			BitmapFactory.Options options = new BitmapFactory.Options();
154			options.inJustDecodeBounds = true;
155			BitmapFactory.decodeFile(file.getAbsolutePath(), options);
156			int imageHeight = options.outHeight;
157			int imageWidth = options.outWidth;
158			message.setBody(mUrl.toString() + "," + file.getSize() + ','
159					+ imageWidth + ',' + imageHeight);
160			message.setType(Message.TYPE_IMAGE);
161			mXmppConnectionService.updateMessage(message);
162		}
163
164	}
165
166	@Override
167	public int getStatus() {
168		return this.mStatus;
169	}
170
171	@Override
172	public long getFileSize() {
173		if (this.file != null) {
174			return this.file.getExpectedSize();
175		} else {
176			return 0;
177		}
178	}
179}