aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/persistance
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/persistance')
-rw-r--r--src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java29
-rw-r--r--src/main/java/eu/siacs/conversations/persistance/FileBackend.java134
2 files changed, 129 insertions, 34 deletions
diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
index e5ea8f90..6879a068 100644
--- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
+++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
@@ -9,6 +9,8 @@ import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.Roster;
+import eu.siacs.conversations.xmpp.jid.Jid;
+
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteCantOpenDatabaseException;
@@ -20,7 +22,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
private static DatabaseBackend instance = null;
private static final String DATABASE_NAME = "history";
- private static final int DATABASE_VERSION = 9;
+ private static final int DATABASE_VERSION = 10;
private static String CREATE_CONTATCS_STATEMENT = "create table "
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
@@ -62,6 +64,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ " TEXT, " + Message.TRUE_COUNTERPART + " TEXT,"
+ Message.BODY + " TEXT, " + Message.ENCRYPTION + " NUMBER, "
+ Message.STATUS + " NUMBER," + Message.TYPE + " NUMBER, "
+ + Message.RELATIVE_FILE_PATH + " TEXT, "
+ Message.REMOTE_MSG_ID + " TEXT, FOREIGN KEY("
+ Message.CONVERSATION + ") REFERENCES "
+ Conversation.TABLENAME + "(" + Conversation.UUID
@@ -108,6 +111,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN "
+ Contact.LAST_PRESENCE + " TEXT");
}
+ if (oldVersion < 10 && newVersion >= 10) {
+ db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "
+ + Message.RELATIVE_FILE_PATH + " TEXT");
+ }
}
public static synchronized DatabaseBackend getInstance(Context context) {
@@ -149,7 +156,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public CopyOnWriteArrayList<Conversation> getConversations(int status) {
- CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<Conversation>();
+ CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
String[] selectionArgs = { Integer.toString(status) };
Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME
@@ -168,7 +175,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
public ArrayList<Message> getMessages(Conversation conversation, int limit,
long timestamp) {
- ArrayList<Message> list = new ArrayList<Message>();
+ ArrayList<Message> list = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
if (timestamp == -1) {
@@ -196,9 +203,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
return list;
}
- public Conversation findConversation(Account account, String contactJid) {
+ public Conversation findConversation(final Account account, final Jid contactJid) {
SQLiteDatabase db = this.getReadableDatabase();
- String[] selectionArgs = { account.getUuid(), contactJid + "%" };
+ String[] selectionArgs = { account.getUuid(), contactJid.toBareJid().toString() + "%" };
Cursor cursor = db.query(Conversation.TABLENAME, null,
Conversation.ACCOUNT + "=? AND " + Conversation.CONTACTJID
+ " like ?", selectionArgs, null, null, null);
@@ -218,7 +225,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public List<Account> getAccounts() {
- List<Account> list = new ArrayList<Account>();
+ List<Account> list = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(Account.TABLENAME, null, null, null, null,
null, null);
@@ -282,15 +289,15 @@ public class DatabaseBackend extends SQLiteOpenHelper {
cursor.close();
}
- public void writeRoster(Roster roster) {
- Account account = roster.getAccount();
- SQLiteDatabase db = this.getWritableDatabase();
+ public void writeRoster(final Roster roster) {
+ final Account account = roster.getAccount();
+ final SQLiteDatabase db = this.getWritableDatabase();
for (Contact contact : roster.getContacts()) {
if (contact.getOption(Contact.Options.IN_ROSTER)) {
db.insert(Contact.TABLENAME, null, contact.getContentValues());
} else {
String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?";
- String[] whereArgs = { account.getUuid(), contact.getJid() };
+ String[] whereArgs = { account.getUuid(), contact.getJid().toString() };
db.delete(Contact.TABLENAME, where, whereArgs);
}
}
@@ -353,7 +360,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public List<Message> getImageMessages(Conversation conversation) {
- ArrayList<Message> list = new ArrayList<Message>();
+ ArrayList<Message> list = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
String[] selectionArgs = { conversation.getUuid(), String.valueOf(Message.TYPE_IMAGE) };
diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
index 0241b77e..9683d38d 100644
--- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
+++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
@@ -7,6 +7,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.URL;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -26,6 +27,8 @@ import android.provider.MediaStore;
import android.util.Base64;
import android.util.Base64OutputStream;
import android.util.Log;
+import android.webkit.MimeTypeMap;
+
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.DownloadableFile;
@@ -53,25 +56,40 @@ public class FileBackend {
}
public DownloadableFile getFile(Message message, boolean decrypted) {
- StringBuilder filename = new StringBuilder();
- filename.append(getConversationsDirectory());
- filename.append(message.getUuid());
- if ((decrypted) || (message.getEncryption() == Message.ENCRYPTION_NONE)) {
- filename.append(".webp");
- } else {
- if (message.getEncryption() == Message.ENCRYPTION_OTR) {
- filename.append(".webp");
+ String path = message.getRelativeFilePath();
+ if (!decrypted && (message.getEncryption() == Message.ENCRYPTION_PGP || message.getEncryption() == Message.ENCRYPTION_DECRYPTED)) {
+ String extension;
+ if (path != null && !path.isEmpty()) {
+ String[] parts = path.split("\\.");
+ extension = "."+parts[parts.length - 1];
+ } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_TEXT) {
+ extension = ".webp";
} else {
- filename.append(".webp.pgp");
+ extension = "";
}
+ return new DownloadableFile(getConversationsFileDirectory()+message.getUuid()+extension+".pgp");
+ } else if (path != null && !path.isEmpty()) {
+ if (path.startsWith("/")) {
+ return new DownloadableFile(path);
+ } else {
+ return new DownloadableFile(getConversationsFileDirectory()+path);
+ }
+ } else {
+ StringBuilder filename = new StringBuilder();
+ filename.append(getConversationsImageDirectory());
+ filename.append(message.getUuid()+".webp");
+ return new DownloadableFile(filename.toString());
}
- return new DownloadableFile(filename.toString());
}
- public static String getConversationsDirectory() {
+ public static String getConversationsFileDirectory() {
+ return Environment.getExternalStorageDirectory().getAbsolutePath()+"/Conversations/";
+ }
+
+ public static String getConversationsImageDirectory() {
return Environment.getExternalStoragePublicDirectory(
- Environment.DIRECTORY_PICTURES).getAbsolutePath()
- + "/Conversations/";
+ Environment.DIRECTORY_PICTURES).getAbsolutePath()
+ + "/Conversations/";
}
public Bitmap resize(Bitmap originalBitmap, int size) {
@@ -103,13 +121,60 @@ public class FileBackend {
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
+ public String getOriginalPath(Uri uri) {
+ String path = null;
+ if (uri.getScheme().equals("file")) {
+ return uri.getPath();
+ } else if (uri.toString().startsWith("content://media/")) {
+ String[] projection = {MediaStore.MediaColumns.DATA};
+ Cursor metaCursor = mXmppConnectionService.getContentResolver().query(uri,
+ projection, null, null, null);
+ if (metaCursor != null) {
+ try {
+ if (metaCursor.moveToFirst()) {
+ path = metaCursor.getString(0);
+ }
+ } finally {
+ metaCursor.close();
+ }
+ }
+ }
+ return path;
+ }
+
+ public DownloadableFile copyFileToPrivateStorage(Message message, Uri uri) throws FileCopyException {
+ try {
+ Log.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage");
+ String mime = mXmppConnectionService.getContentResolver().getType(uri);
+ String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mime);
+ message.setRelativeFilePath(message.getUuid() + "." + extension);
+ DownloadableFile file = mXmppConnectionService.getFileBackend().getFile(message);
+ OutputStream os = new FileOutputStream(file);
+ InputStream is = mXmppConnectionService.getContentResolver().openInputStream(uri);
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = is.read(buffer)) > 0) {
+ os.write(buffer, 0, length);
+ }
+ os.flush();
+ os.close();
+ is.close();
+ Log.d(Config.LOGTAG, "output file name " + mXmppConnectionService.getFileBackend().getFile(message));
+ return file;
+ } catch (FileNotFoundException e) {
+ throw new FileCopyException(R.string.error_file_not_found);
+ } catch (IOException e) {
+ throw new FileCopyException(R.string.error_io_exception);
+ }
+ }
+
public DownloadableFile copyImageToPrivateStorage(Message message, Uri image)
- throws ImageCopyException {
+ throws FileCopyException {
return this.copyImageToPrivateStorage(message, image, 0);
}
private DownloadableFile copyImageToPrivateStorage(Message message,
- Uri image, int sampleSize) throws ImageCopyException {
+ Uri image, int sampleSize) throws FileCopyException {
try {
InputStream is = mXmppConnectionService.getContentResolver()
.openInputStream(image);
@@ -125,7 +190,7 @@ public class FileBackend {
originalBitmap = BitmapFactory.decodeStream(is, null, options);
is.close();
if (originalBitmap == null) {
- throw new ImageCopyException(R.string.error_not_an_image_file);
+ throw new FileCopyException(R.string.error_not_an_image_file);
}
Bitmap scalledBitmap = resize(originalBitmap, IMAGE_SIZE);
originalBitmap = null;
@@ -137,7 +202,7 @@ public class FileBackend {
boolean success = scalledBitmap.compress(
Bitmap.CompressFormat.WEBP, 75, os);
if (!success) {
- throw new ImageCopyException(R.string.error_compressing_image);
+ throw new FileCopyException(R.string.error_compressing_image);
}
os.flush();
os.close();
@@ -147,18 +212,18 @@ public class FileBackend {
message.setBody(Long.toString(size) + ',' + width + ',' + height);
return file;
} catch (FileNotFoundException e) {
- throw new ImageCopyException(R.string.error_file_not_found);
+ throw new FileCopyException(R.string.error_file_not_found);
} catch (IOException e) {
- throw new ImageCopyException(R.string.error_io_exception);
+ throw new FileCopyException(R.string.error_io_exception);
} catch (SecurityException e) {
- throw new ImageCopyException(
+ throw new FileCopyException(
R.string.error_security_exception_during_image_copy);
} catch (OutOfMemoryError e) {
++sampleSize;
if (sampleSize <= 3) {
return copyImageToPrivateStorage(message, image, sampleSize);
} else {
- throw new ImageCopyException(R.string.error_out_of_memory);
+ throw new FileCopyException(R.string.error_out_of_memory);
}
}
}
@@ -400,11 +465,34 @@ public class FileBackend {
return Uri.parse("file://" + file.getAbsolutePath());
}
- public class ImageCopyException extends Exception {
+ public void updateFileParams(Message message) {
+ updateFileParams(message,null);
+ }
+
+ public void updateFileParams(Message message, URL url) {
+ DownloadableFile file = getFile(message);
+ if (message.getType() == Message.TYPE_IMAGE || file.getMimeType().startsWith("image/")) {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeFile(file.getAbsolutePath(), options);
+ int imageHeight = options.outHeight;
+ int imageWidth = options.outWidth;
+ if (url == null) {
+ message.setBody(Long.toString(file.getSize()) + '|' + imageWidth + '|' + imageHeight);
+ } else {
+ message.setBody(url.toString()+"|"+Long.toString(file.getSize()) + '|' + imageWidth + '|' + imageHeight);
+ }
+ } else {
+ message.setBody(Long.toString(file.getSize()));
+ }
+
+ }
+
+ public class FileCopyException extends Exception {
private static final long serialVersionUID = -1010013599132881427L;
private int resId;
- public ImageCopyException(int resId) {
+ public FileCopyException(int resId) {
this.resId = resId;
}