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;
  9
 10import android.content.Context;
 11import android.graphics.Bitmap;
 12import android.graphics.BitmapFactory;
 13import android.net.Uri;
 14import android.util.Log;
 15import android.util.LruCache;
 16
 17import eu.siacs.conversations.entities.Conversation;
 18import eu.siacs.conversations.entities.Message;
 19import eu.siacs.conversations.xmpp.jingle.JingleFile;
 20
 21public class FileBackend {
 22
 23	private static int IMAGE_SIZE = 1920;
 24
 25	private Context context;
 26	private LruCache<String, Bitmap> thumbnailCache;
 27
 28	public FileBackend(Context context) {
 29		this.context = context;
 30
 31		int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
 32		int cacheSize = maxMemory / 8;
 33		thumbnailCache = new LruCache<String, Bitmap>(cacheSize) {
 34			@Override
 35			protected int sizeOf(String key, Bitmap bitmap) {
 36				return bitmap.getByteCount() / 1024;
 37			}
 38		};
 39
 40	}
 41
 42	public JingleFile getJingleFile(Message message) {
 43		Conversation conversation = message.getConversation();
 44		String prefix = context.getFilesDir().getAbsolutePath();
 45		String path = prefix + "/" + conversation.getAccount().getJid() + "/"
 46				+ conversation.getContactJid();
 47		String filename = message.getUuid() + ".webp";
 48		return new JingleFile(path + "/" + filename);
 49	}
 50
 51	private Bitmap resize(Bitmap originalBitmap, int size) {
 52		int w = originalBitmap.getWidth();
 53		int h = originalBitmap.getHeight();
 54		if (Math.max(w, h) > size) {
 55			int scalledW;
 56			int scalledH;
 57			if (w <= h) {
 58				scalledW = (int) (w / ((double) h / size));
 59				scalledH = size;
 60			} else {
 61				scalledW = size;
 62				scalledH = (int) (h / ((double) w / size));
 63			}
 64			Bitmap scalledBitmap = Bitmap.createScaledBitmap(originalBitmap,
 65					scalledW, scalledH, true);
 66			return scalledBitmap;
 67		} else {
 68			return originalBitmap;
 69		}
 70	}
 71
 72	public JingleFile copyImageToPrivateStorage(Message message, Uri image) {
 73		try {
 74			InputStream is = context.getContentResolver()
 75					.openInputStream(image);
 76			JingleFile file = getJingleFile(message);
 77			file.getParentFile().mkdirs();
 78			file.createNewFile();
 79			OutputStream os = new FileOutputStream(file);
 80			Bitmap originalBitmap = BitmapFactory.decodeStream(is);
 81			is.close();
 82			Bitmap scalledBitmap = resize(originalBitmap, IMAGE_SIZE);
 83			boolean success = scalledBitmap.compress(
 84					Bitmap.CompressFormat.WEBP, 75, os);
 85			if (!success) {
 86				// Log.d("xmppService", "couldnt compress");
 87			}
 88			os.close();
 89			return file;
 90		} catch (FileNotFoundException e) {
 91			// TODO Auto-generated catch block
 92			e.printStackTrace();
 93		} catch (IOException e) {
 94			// TODO Auto-generated catch block
 95			e.printStackTrace();
 96		}
 97
 98		return null;
 99	}
100
101	public Bitmap getImageFromMessage(Message message) {
102		return BitmapFactory.decodeFile(getJingleFile(message)
103				.getAbsolutePath());
104	}
105
106	public Bitmap getThumbnailFromMessage(Message message, int size)
107			throws FileNotFoundException {
108		Bitmap thumbnail = thumbnailCache.get(message.getUuid());
109		if (thumbnail == null) {
110			Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message)
111					.getAbsolutePath());
112			if (fullsize == null) {
113				throw new FileNotFoundException();
114			}
115			thumbnail = resize(fullsize, size);
116			this.thumbnailCache.put(message.getUuid(), thumbnail);
117		}
118		return thumbnail;
119	}
120
121	public void removeFiles(Conversation conversation) {
122		String prefix = context.getFilesDir().getAbsolutePath();
123		String path = prefix + "/" + conversation.getAccount().getJid() + "/"
124				+ conversation.getContactJid();
125		File file = new File(path);
126		try {
127			this.deleteFile(file);
128		} catch (IOException e) {
129			Log.d("xmppService",
130					"error deleting file: " + file.getAbsolutePath());
131		}
132	}
133
134	private void deleteFile(File f) throws IOException {
135		if (f.isDirectory()) {
136			for (File c : f.listFiles())
137				deleteFile(c);
138		}
139		f.delete();
140	}
141}