FileBackend.java

  1package eu.siacs.conversations.persistance;
  2
  3import java.io.BufferedInputStream;
  4import java.io.File;
  5import java.io.FileInputStream;
  6import java.io.FileNotFoundException;
  7import java.io.FileOutputStream;
  8import java.io.IOException;
  9import java.io.InputStream;
 10import java.io.OutputStream;
 11import java.security.MessageDigest;
 12import java.security.NoSuchAlgorithmException;
 13
 14import android.content.Context;
 15import android.graphics.Bitmap;
 16import android.graphics.BitmapFactory;
 17import android.net.Uri;
 18import android.util.Log;
 19import android.util.LruCache;
 20
 21import eu.siacs.conversations.entities.Conversation;
 22import eu.siacs.conversations.entities.Message;
 23import eu.siacs.conversations.utils.CryptoHelper;
 24
 25public class FileBackend {
 26
 27	private static int IMAGE_SIZE = 1920;
 28
 29	private Context context;
 30	private LruCache<String, Bitmap> thumbnailCache;
 31
 32	public FileBackend(Context context) {
 33		this.context = context;
 34		
 35		int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
 36		int cacheSize = maxMemory / 8;
 37		thumbnailCache = new LruCache<String, Bitmap>(cacheSize) {
 38			@Override
 39			protected int sizeOf(String key, Bitmap bitmap) {
 40				return bitmap.getByteCount() / 1024;
 41			}
 42		};
 43
 44	}
 45
 46	public File getImageFile(Message message) {
 47		Conversation conversation = message.getConversation();
 48		String prefix = context.getFilesDir().getAbsolutePath();
 49		String path = prefix + "/" + conversation.getAccount().getJid() + "/"
 50				+ conversation.getContactJid();
 51		String filename = message.getUuid() + ".webp";
 52		return new File(path + "/" + filename);
 53	}
 54	
 55	private Bitmap resize(Bitmap originalBitmap, int size) {
 56		int w = originalBitmap.getWidth();
 57		int h = originalBitmap.getHeight();
 58		if (Math.max(w, h) > size) {
 59			int scalledW;
 60			int scalledH;
 61			if (w <= h) {
 62				scalledW = (int) (w / ((double) h / size));
 63				scalledH = size;
 64			} else {
 65				scalledW = size;
 66				scalledH = (int) (h / ((double) w / size));
 67			}
 68			Bitmap scalledBitmap = Bitmap.createScaledBitmap(
 69					originalBitmap, scalledW, scalledH, true);
 70			return scalledBitmap;
 71		} else {
 72			return originalBitmap;
 73		}
 74	}
 75
 76	public File copyImageToPrivateStorage(Message message, Uri image) {
 77		try {
 78			InputStream is = context.getContentResolver()
 79					.openInputStream(image);
 80			File file = getImageFile(message);
 81			file.getParentFile().mkdirs();
 82			file.createNewFile();
 83			OutputStream os = new FileOutputStream(file);
 84			Bitmap originalBitmap = BitmapFactory.decodeStream(is);
 85			is.close();
 86			Bitmap scalledBitmap = resize(originalBitmap, IMAGE_SIZE);
 87			boolean success = scalledBitmap.compress(Bitmap.CompressFormat.WEBP,75,os);
 88			if (!success) {
 89				Log.d("xmppService", "couldnt compress");
 90			}
 91			os.close();
 92			message.setBody(this.createSha1(file));
 93			return file;
 94		} catch (FileNotFoundException e) {
 95			// TODO Auto-generated catch block
 96			e.printStackTrace();
 97		} catch (IOException e) {
 98			// TODO Auto-generated catch block
 99			e.printStackTrace();
100		}
101
102		return null;
103	}
104
105	public Bitmap getImageFromMessage(Message message) {
106		return BitmapFactory
107				.decodeFile(getImageFile(message).getAbsolutePath());
108	}
109
110	public Bitmap getThumbnailFromMessage(Message message, int size) {
111		Bitmap thumbnail = thumbnailCache.get(message.getUuid());
112		if (thumbnail==null) {
113			Log.d("xmppService","creating new thumbnail" + message.getUuid());
114			Bitmap fullsize = BitmapFactory.decodeFile(getImageFile(message)
115					.getAbsolutePath());
116			thumbnail = resize(fullsize, size);
117			this.thumbnailCache.put(message.getUuid(), thumbnail);
118		}
119		return thumbnail;
120	}
121	
122	private String createSha1(final File file) {
123		InputStream fis = null;
124		try {
125			MessageDigest digest = MessageDigest.getInstance("SHA-1");
126			fis = new FileInputStream(file);
127		    int n = 0;
128		    byte[] buffer = new byte[8192];
129		    while (n != -1) {
130		        n = fis.read(buffer);
131		        if (n > 0) {
132		            digest.update(buffer, 0, n);
133		        }
134		    }
135		    fis.close();
136		    return CryptoHelper.bytesToHex(digest.digest());
137		} catch (NoSuchAlgorithmException e) {
138			return null;
139		} catch (FileNotFoundException e) {
140			if (fis!=null) {
141				try {
142					fis.close();
143					return null;
144				} catch (IOException e1) {
145					return null;
146				}
147			}
148		} catch (IOException e) {
149			if (fis!=null) {
150				try {
151					fis.close();
152					return null;
153				} catch (IOException e1) {
154					return null;
155				}
156			}
157		}
158		return null;
159	}
160}