scan all files in case some files were previously marked as deleted by accident

This commit is contained in:
Daniel Gultsch 2019-01-24 15:03:58 +01:00
parent 04d1b92a79
commit 8fbe445c99
3 changed files with 72 additions and 13 deletions

View file

@ -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<DatabaseBackend.FilePathInfo> 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();

View file

@ -847,12 +847,25 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.endTransaction();
}
public List<FilePath> getAllNonDeletedFilePath() {
public void markFilesAsChanged(List<FilePathInfo> 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<FilePathInfo> 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<FilePath> 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<FilePathInfo> 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(),

View file

@ -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<String> deletedUuids = new ArrayList<>();
final List<DatabaseBackend.FilePath> relativeFilePaths = databaseBackend.getAllNonDeletedFilePath();
for(final DatabaseBackend.FilePath filePath : relativeFilePaths) {
final long start = SystemClock.elapsedRealtime();
final List<DatabaseBackend.FilePathInfo> relativeFilePaths = databaseBackend.getFilePathInfo();
final List<DatabaseBackend.FilePathInfo> 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<DatabaseBackend.FilePathInfo> infos) {
boolean changed = false;
for (Conversation conversation : getConversations()) {
changed |= conversation.markAsChanged(infos);
}
if (changed) {
updateConversationUi();
}
}
public void populateWithOrderedConversations(final List<Conversation> list) {
populateWithOrderedConversations(list, true, true);
}