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 // Log.d("xmppService", "couldnt compress");
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 // TODO Auto-generated catch block
116 e.printStackTrace();
117 } catch (IOException e) {
118 // TODO Auto-generated catch block
119 e.printStackTrace();
120 }
121
122 return null;
123 }
124
125 public Bitmap getImageFromMessage(Message message) {
126 return BitmapFactory.decodeFile(getJingleFile(message)
127 .getAbsolutePath());
128 }
129
130 public Bitmap getThumbnail(Message message, int size, boolean cacheOnly)
131 throws FileNotFoundException {
132 Bitmap thumbnail = thumbnailCache.get(message.getUuid());
133 if ((thumbnail == null)&&(!cacheOnly)) {
134 Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message)
135 .getAbsolutePath());
136 if (fullsize == null) {
137 throw new FileNotFoundException();
138 }
139 thumbnail = resize(fullsize, size);
140 this.thumbnailCache.put(message.getUuid(), thumbnail);
141 }
142 return thumbnail;
143 }
144
145 public void removeFiles(Conversation conversation) {
146 String prefix = context.getFilesDir().getAbsolutePath();
147 String path = prefix + "/" + conversation.getAccount().getJid() + "/"
148 + conversation.getContactJid();
149 File file = new File(path);
150 try {
151 this.deleteFile(file);
152 } catch (IOException e) {
153 Log.d("xmppService",
154 "error deleting file: " + file.getAbsolutePath());
155 }
156 }
157
158 private void deleteFile(File f) throws IOException {
159 if (f.isDirectory()) {
160 for (File c : f.listFiles())
161 deleteFile(c);
162 }
163 f.delete();
164 }
165}