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.graphics.BitmapFactory;
 13
 14import eu.siacs.conversations.entities.Downloadable;
 15import eu.siacs.conversations.entities.DownloadableFile;
 16import eu.siacs.conversations.entities.Message;
 17import eu.siacs.conversations.services.XmppConnectionService;
 18
 19public class HttpConnection implements Downloadable {
 20
 21	private HttpConnectionManager mHttpConnectionManager;
 22	private XmppConnectionService mXmppConnectionService;
 23
 24	private URL mUrl;
 25	private Message message;
 26	private DownloadableFile file;
 27	private long mPreviousFileSize = 0;
 28	private int mStatus = Downloadable.STATUS_UNKNOWN;
 29
 30	public HttpConnection(HttpConnectionManager manager) {
 31		this.mHttpConnectionManager = manager;
 32		this.mXmppConnectionService = manager.getXmppConnectionService();
 33	}
 34
 35	@Override
 36	public void start() {
 37		changeStatus(STATUS_DOWNLOADING);
 38		new Thread(new FileDownloader()).start();
 39	}
 40
 41	public void init(Message message) {
 42		this.message = message;
 43		this.message.setDownloadable(this);
 44		try {
 45			mUrl = new URL(message.getBody());
 46			this.file = mXmppConnectionService.getFileBackend()
 47					.getConversationsFile(message, false);
 48			checkFileSize();
 49		} catch (MalformedURLException e) {
 50			this.cancel();
 51		}
 52	}
 53
 54	public void init(Message message, URL url) {
 55		this.message = message;
 56		this.message.setDownloadable(this);
 57		this.mUrl = url;
 58		this.file = mXmppConnectionService.getFileBackend()
 59				.getConversationsFile(message, false);
 60		this.mPreviousFileSize = message.getImageParams().size;
 61		checkFileSize();
 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		message.setBody(mUrl.toString());
 73		mXmppConnectionService.updateMessage(message);
 74	}
 75
 76	private void finish() {
 77		message.setDownloadable(null);
 78		mHttpConnectionManager.finishConnection(this);
 79	}
 80
 81	private void changeStatus(int status) {
 82		this.mStatus = status;
 83		mXmppConnectionService.updateConversationUi();
 84	}
 85
 86	private class FileSizeChecker implements Runnable {
 87
 88		@Override
 89		public void run() {
 90			long size;
 91			try {
 92				size = retrieveFileSize();
 93			} catch (IOException e) {
 94				cancel();
 95				return;
 96			}
 97			file.setExpectedSize(size);
 98			message.setType(Message.TYPE_IMAGE);
 99			if (size <= mHttpConnectionManager.getAutoAcceptFileSize()
100					|| size == mPreviousFileSize) {
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			mXmppConnectionService.updateMessage(message);
168		}
169
170	}
171
172	@Override
173	public int getStatus() {
174		return this.mStatus;
175	}
176
177	@Override
178	public long getFileSize() {
179		if (this.file != null) {
180			return this.file.getExpectedSize();
181		} else {
182			return 0;
183		}
184	}
185}