FileBackend.java

  1package eu.siacs.conversations.persistance;
  2
  3import java.io.File;
  4import java.io.FileNotFoundException;
  5import java.io.FileOutputStream;
  6import java.io.IOException;
  7import java.io.InputStream;
  8import java.io.OutputStream;
  9import java.lang.ref.WeakReference;
 10
 11import android.content.Context;
 12import android.graphics.Bitmap;
 13import android.graphics.BitmapFactory;
 14import android.net.Uri;
 15import android.util.Log;
 16import android.util.LruCache;
 17import android.view.View;
 18import android.widget.ImageView;
 19import android.widget.TextView;
 20
 21import eu.siacs.conversations.entities.Account;
 22import eu.siacs.conversations.entities.Conversation;
 23import eu.siacs.conversations.entities.Message;
 24import eu.siacs.conversations.services.XmppConnectionService;
 25import eu.siacs.conversations.xmpp.jingle.JingleFile;
 26
 27public class FileBackend {
 28
 29	private static int IMAGE_SIZE = 1920;
 30
 31	private Context context;
 32	private LruCache<String, Bitmap> thumbnailCache;
 33
 34	public FileBackend(Context context) {
 35		this.context = context;
 36		int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
 37		int cacheSize = maxMemory / 8;
 38		thumbnailCache = new LruCache<String, Bitmap>(cacheSize) {
 39			@Override
 40			protected int sizeOf(String key, Bitmap bitmap) {
 41				return bitmap.getByteCount() / 1024;
 42			}
 43		};
 44
 45	}
 46	
 47	public LruCache<String, Bitmap> getThumbnailCache() {
 48		return thumbnailCache;
 49	}
 50	
 51	public JingleFile getJingleFile(Message message) {
 52		return getJingleFile(message, true);
 53	}
 54
 55	public JingleFile getJingleFile(Message message, boolean decrypted) {
 56		Conversation conversation = message.getConversation();
 57		String prefix = context.getFilesDir().getAbsolutePath();
 58		String path = prefix + "/" + conversation.getAccount().getJid() + "/"
 59				+ conversation.getContactJid();
 60		String filename;
 61		if ((decrypted)||(message.getEncryption() == Message.ENCRYPTION_NONE)) {
 62			filename = message.getUuid() + ".webp";
 63		} else {
 64			filename = message.getUuid() + ".webp.pgp";
 65		}
 66		return new JingleFile(path + "/" + filename);
 67	}
 68
 69	public Bitmap resize(Bitmap originalBitmap, int size) {
 70		int w = originalBitmap.getWidth();
 71		int h = originalBitmap.getHeight();
 72		if (Math.max(w, h) > size) {
 73			int scalledW;
 74			int scalledH;
 75			if (w <= h) {
 76				scalledW = (int) (w / ((double) h / size));
 77				scalledH = size;
 78			} else {
 79				scalledW = size;
 80				scalledH = (int) (h / ((double) w / size));
 81			}
 82			Bitmap scalledBitmap = Bitmap.createScaledBitmap(originalBitmap,
 83					scalledW, scalledH, true);
 84			return scalledBitmap;
 85		} else {
 86			return originalBitmap;
 87		}
 88	}
 89
 90	public JingleFile copyImageToPrivateStorage(Message message, Uri image) {
 91		try {
 92			Log.d("xmppService","copying file: "+image.toString()+ " to internal storage");
 93			InputStream is = context.getContentResolver()
 94					.openInputStream(image);
 95			JingleFile file = getJingleFile(message);
 96			file.getParentFile().mkdirs();
 97			file.createNewFile();
 98			OutputStream os = new FileOutputStream(file);
 99			Bitmap originalBitmap = BitmapFactory.decodeStream(is);
100			is.close();
101			Bitmap scalledBitmap = resize(originalBitmap, IMAGE_SIZE);
102			boolean success = scalledBitmap.compress(
103					Bitmap.CompressFormat.WEBP, 75, os);
104			if (!success) {
105				return null;
106			}
107			os.flush();
108			os.close();
109			long size = file.getSize();
110			int width = scalledBitmap.getWidth();
111			int height = scalledBitmap.getHeight();
112			message.setBody(""+size+","+width+","+height);
113			return file;
114		} catch (FileNotFoundException e) {
115			return null;
116		} catch (IOException e) {
117			return null;
118		} catch (SecurityException e) {
119			return null;
120		}
121	}
122
123	public Bitmap getImageFromMessage(Message message) {
124		return BitmapFactory.decodeFile(getJingleFile(message)
125				.getAbsolutePath());
126	}
127
128	public Bitmap getThumbnail(Message message, int size, boolean cacheOnly)
129			throws FileNotFoundException {
130		Bitmap thumbnail = thumbnailCache.get(message.getUuid());
131		if ((thumbnail == null)&&(!cacheOnly)) {
132			Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message)
133					.getAbsolutePath());
134			if (fullsize == null) {
135				throw new FileNotFoundException();
136			}
137			thumbnail = resize(fullsize, size);
138			this.thumbnailCache.put(message.getUuid(), thumbnail);
139		}
140		return thumbnail;
141	}
142
143	public void removeFiles(Conversation conversation) {
144		String prefix = context.getFilesDir().getAbsolutePath();
145		String path = prefix + "/" + conversation.getAccount().getJid() + "/"
146				+ conversation.getContactJid();
147		File file = new File(path);
148		try {
149			this.deleteFile(file);
150		} catch (IOException e) {
151			Log.d("xmppService",
152					"error deleting file: " + file.getAbsolutePath());
153		}
154	}
155
156	private void deleteFile(File f) throws IOException {
157		if (f.isDirectory()) {
158			for (File c : f.listFiles())
159				deleteFile(c);
160		}
161		f.delete();
162	}
163}