diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index d9db92934..f629274b2 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -23,6 +23,7 @@ import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.OmemoSetting; import eu.siacs.conversations.crypto.PgpDecryptionService; import eu.siacs.conversations.crypto.axolotl.AxolotlService; +import eu.siacs.conversations.persistance.DatabaseBackend; import eu.siacs.conversations.services.QuickConversationsService; import eu.siacs.conversations.utils.JidHelper; import eu.siacs.conversations.xmpp.InvalidJid; @@ -209,6 +210,24 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl return deleted; } + public boolean markAsChanged(final List files) { + boolean changed = false; + final PgpDecryptionService pgpDecryptionService = account.getPgpDecryptionService(); + synchronized (this.messages) { + for(Message message : this.messages) { + for(final DatabaseBackend.FilePathInfo file : files) + if (file.uuid.toString().equals(message.getUuid())) { + message.setDeleted(file.deleted); + changed = true; + if (file.deleted && message.getEncryption() == Message.ENCRYPTION_PGP && pgpDecryptionService != null) { + pgpDecryptionService.discard(message); + } + } + } + } + return changed; + } + public void clearMessages() { synchronized (this.messages) { this.messages.clear(); diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 152662708..34758fe3e 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -847,12 +847,25 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.endTransaction(); } - public List getAllNonDeletedFilePath() { + public void markFilesAsChanged(List files) { + SQLiteDatabase db = this.getReadableDatabase(); + final String where = Message.UUID + "=?"; + db.beginTransaction(); + for (FilePathInfo info : files) { + final ContentValues contentValues = new ContentValues(); + contentValues.put(Message.DELETED, info.deleted ? 1 : 0); + db.update(Message.TABLENAME, contentValues, where, new String[]{info.uuid.toString()}); + } + db.setTransactionSuccessful(); + db.endTransaction(); + } + + public List getFilePathInfo() { final SQLiteDatabase db = this.getReadableDatabase(); - final Cursor cursor = db.query(Message.TABLENAME, new String[]{Message.UUID, Message.RELATIVE_FILE_PATH}, "type in (1,2) and deleted=0 and "+Message.RELATIVE_FILE_PATH+" is not null", null, null, null, null); - final List list = new ArrayList<>(); + final Cursor cursor = db.query(Message.TABLENAME, new String[]{Message.UUID, Message.RELATIVE_FILE_PATH, Message.DELETED}, "type in (1,2) and "+Message.RELATIVE_FILE_PATH+" is not null", null, null, null, null); + final List list = new ArrayList<>(); while (cursor != null && cursor.moveToNext()) { - list.add(new FilePath(cursor.getString(0), cursor.getString(1))); + list.add(new FilePathInfo(cursor.getString(0), cursor.getString(1), cursor.getInt(2) > 0)); } if (cursor != null) { cursor.close(); @@ -883,6 +896,21 @@ public class DatabaseBackend extends SQLiteOpenHelper { } } + public static class FilePathInfo extends FilePath { + public boolean deleted; + + private FilePathInfo(String uuid, String path, boolean deleted) { + super(uuid,path); + this.deleted = deleted; + } + + public boolean setDeleted(boolean deleted) { + final boolean changed = deleted != this.deleted; + this.deleted = deleted; + return changed; + } + } + public Conversation findConversation(final Account account, final Jid contactJid) { SQLiteDatabase db = this.getReadableDatabase(); String[] selectionArgs = {account.getUuid(), diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 47b9ef731..ae02a9357 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1063,22 +1063,24 @@ public class XmppConnectionService extends Service { Log.d(Config.LOGTAG, "Do not check for deleted files because service has been destroyed"); return; } - final List deletedUuids = new ArrayList<>(); - final List relativeFilePaths = databaseBackend.getAllNonDeletedFilePath(); - for(final DatabaseBackend.FilePath filePath : relativeFilePaths) { + final long start = SystemClock.elapsedRealtime(); + final List relativeFilePaths = databaseBackend.getFilePathInfo(); + final List changed = new ArrayList<>(); + for(final DatabaseBackend.FilePathInfo filePath : relativeFilePaths) { if (destroyed) { Log.d(Config.LOGTAG, "Stop checking for deleted files because service has been destroyed"); return; } final File file = fileBackend.getFileForPath(filePath.path); - if (!file.exists()) { - deletedUuids.add(filePath.uuid.toString()); + if (filePath.setDeleted(!file.exists())) { + changed.add(filePath); } } - Log.d(Config.LOGTAG,"found "+deletedUuids.size()+" deleted files on start up. total="+relativeFilePaths.size()); - if (deletedUuids.size() > 0) { - databaseBackend.markFileAsDeleted(deletedUuids); - markUuidsAsDeletedFiles(deletedUuids); + final long duration = SystemClock.elapsedRealtime() - start; + Log.d(Config.LOGTAG,"found "+changed.size()+" changed files on start up. total="+relativeFilePaths.size()+". ("+duration+"ms)"); + if (changed.size() > 0) { + databaseBackend.markFilesAsChanged(changed); + markChangedFiles(changed); } } @@ -1671,6 +1673,16 @@ public class XmppConnectionService extends Service { } } + private void markChangedFiles(List infos) { + boolean changed = false; + for (Conversation conversation : getConversations()) { + changed |= conversation.markAsChanged(infos); + } + if (changed) { + updateConversationUi(); + } + } + public void populateWithOrderedConversations(final List list) { populateWithOrderedConversations(list, true, true); }