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}