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