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