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