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 InputStream is = context.getContentResolver()
76 .openInputStream(image);
77 JingleFile file = getJingleFile(message);
78 file.getParentFile().mkdirs();
79 file.createNewFile();
80 OutputStream os = new FileOutputStream(file);
81 Bitmap originalBitmap = BitmapFactory.decodeStream(is);
82 is.close();
83 Bitmap scalledBitmap = resize(originalBitmap, IMAGE_SIZE);
84 boolean success = scalledBitmap.compress(
85 Bitmap.CompressFormat.WEBP, 75, os);
86 if (!success) {
87 // Log.d("xmppService", "couldnt compress");
88 }
89 os.close();
90 return file;
91 } catch (FileNotFoundException e) {
92 // TODO Auto-generated catch block
93 e.printStackTrace();
94 } catch (IOException e) {
95 // TODO Auto-generated catch block
96 e.printStackTrace();
97 }
98
99 return null;
100 }
101
102 public Bitmap getImageFromMessage(Message message) {
103 return BitmapFactory.decodeFile(getJingleFile(message)
104 .getAbsolutePath());
105 }
106
107 public Bitmap getThumbnailFromMessage(Message message, int size)
108 throws FileNotFoundException {
109 Bitmap thumbnail = thumbnailCache.get(message.getUuid());
110 if (thumbnail == null) {
111 Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message)
112 .getAbsolutePath());
113 if (fullsize == null) {
114 throw new FileNotFoundException();
115 }
116 thumbnail = resize(fullsize, size);
117 this.thumbnailCache.put(message.getUuid(), thumbnail);
118 }
119 return thumbnail;
120 }
121
122 public void removeFiles(Conversation conversation) {
123 String prefix = context.getFilesDir().getAbsolutePath();
124 String path = prefix + "/" + conversation.getAccount().getJid() + "/"
125 + conversation.getContactJid();
126 File file = new File(path);
127 try {
128 this.deleteFile(file);
129 } catch (IOException e) {
130 Log.d("xmppService",
131 "error deleting file: " + file.getAbsolutePath());
132 }
133 }
134
135 private void deleteFile(File f) throws IOException {
136 if (f.isDirectory()) {
137 for (File c : f.listFiles())
138 deleteFile(c);
139 }
140 f.delete();
141 }
142}