From cd995aca565b3a1d7573ba712ed05ddd601de1bc Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Wed, 30 Sep 2020 14:35:02 -0400 Subject: [PATCH] Fix incorrect mention association when messages are deleted. --- .../securesms/database/MentionDatabase.java | 19 +++++++++++++++++++ .../securesms/database/MmsDatabase.java | 5 +++++ .../securesms/database/ThreadDatabase.java | 4 ++++ .../mediasend/MediaSendViewModel.java | 15 ++++++++------- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MentionDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MentionDatabase.java index 420a8c988f..2e18039f89 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MentionDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MentionDatabase.java @@ -125,6 +125,25 @@ public class MentionDatabase extends Database { } } + void deleteMentionsForMessage(long messageId) { + SQLiteDatabase db = databaseHelper.getWritableDatabase(); + String where = MESSAGE_ID + " = ?"; + + db.delete(TABLE_NAME, where, SqlUtil.buildArgs(messageId)); + } + + void deleteAbandonedMentions() { + SQLiteDatabase db = databaseHelper.getWritableDatabase(); + String where = MESSAGE_ID + " NOT IN (SELECT _id FROM " + MmsDatabase.TABLE_NAME + ")"; + + db.delete(TABLE_NAME, where, null); + } + + void deleteAllMentions() { + SQLiteDatabase db = databaseHelper.getWritableDatabase(); + db.delete(TABLE_NAME, null, null); + } + private @NonNull Map> readMentions(@Nullable Cursor cursor) { Map> mentions = new HashMap<>(); while (cursor != null && cursor.moveToNext()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index 7bd9babebf..a3884e2ea2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -704,6 +704,7 @@ public class MmsDatabase extends MessageDatabase { db.update(TABLE_NAME, values, ID_WHERE, new String[] { String.valueOf(messageId) }); DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentsForMessage(messageId); + DatabaseFactory.getMentionDatabase(context).deleteMentionsForMessage(messageId); long threadId = getThreadIdForMessage(messageId); DatabaseFactory.getThreadDatabase(context).update(threadId, false); @@ -1467,6 +1468,9 @@ public class MmsDatabase extends MessageDatabase { GroupReceiptDatabase groupReceiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); groupReceiptDatabase.deleteRowsForMessage(messageId); + MentionDatabase mentionDatabase = DatabaseFactory.getMentionDatabase(context); + mentionDatabase.deleteMentionsForMessage(messageId); + SQLiteDatabase database = databaseHelper.getWritableDatabase(); database.delete(TABLE_NAME, ID_WHERE, new String[] {messageId+""}); boolean threadDeleted = DatabaseFactory.getThreadDatabase(context).update(threadId, false); @@ -1601,6 +1605,7 @@ public class MmsDatabase extends MessageDatabase { public void deleteAllThreads() { DatabaseFactory.getAttachmentDatabase(context).deleteAllAttachments(); DatabaseFactory.getGroupReceiptDatabase(context).deleteAllRows(); + DatabaseFactory.getMentionDatabase(context).deleteAllMentions(); SQLiteDatabase database = databaseHelper.getWritableDatabase(); database.delete(TABLE_NAME, null, null); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index 8a313b06e0..d19c3f8108 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -270,6 +270,7 @@ public class ThreadDatabase extends Database { AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); GroupReceiptDatabase groupReceiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + MentionDatabase mentionDatabase = DatabaseFactory.getMentionDatabase(context); try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] { ID }, null, null, null, null, null)) { while (cursor != null && cursor.moveToNext()) { @@ -283,6 +284,7 @@ public class ThreadDatabase extends Database { mmsSmsDatabase.deleteAbandonedMessages(); attachmentDatabase.trimAllAbandonedAttachments(); groupReceiptDatabase.deleteAbandonedRows(); + mentionDatabase.deleteAbandonedMentions(); attachmentDatabase.deleteAbandonedAttachmentFiles(); db.setTransactionSuccessful(); } finally { @@ -304,6 +306,7 @@ public class ThreadDatabase extends Database { AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); GroupReceiptDatabase groupReceiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context); MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); + MentionDatabase mentionDatabase = DatabaseFactory.getMentionDatabase(context); db.beginTransaction(); @@ -312,6 +315,7 @@ public class ThreadDatabase extends Database { mmsSmsDatabase.deleteAbandonedMessages(); attachmentDatabase.trimAllAbandonedAttachments(); groupReceiptDatabase.deleteAbandonedRows(); + mentionDatabase.deleteAbandonedMentions(); attachmentDatabase.deleteAbandonedAttachmentFiles(); db.setTransactionSuccessful(); } finally { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendViewModel.java index fc54acba4b..28fc30e014 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendViewModel.java @@ -459,10 +459,11 @@ class MediaSendViewModel extends ViewModel { throw new IllegalStateException("Provided recipients to send to, but this is SMS!"); } - MutableLiveData result = new MutableLiveData<>(); - Runnable dialogRunnable = () -> event.postValue(Event.SHOW_RENDER_PROGRESS); - String trimmedBody = isViewOnce() ? "" : body.toString().trim(); - List initialMedia = getSelectedMediaOrDefault(); + MutableLiveData result = new MutableLiveData<>(); + Runnable dialogRunnable = () -> event.postValue(Event.SHOW_RENDER_PROGRESS); + String trimmedBody = isViewOnce() ? "" : body.toString().trim(); + List initialMedia = getSelectedMediaOrDefault(); + List trimmedMentions = isViewOnce() ? Collections.emptyList() : mentions; Preconditions.checkState(initialMedia.size() > 0, "No media to send!"); @@ -477,7 +478,7 @@ class MediaSendViewModel extends ViewModel { if (isSms || MessageSender.isLocalSelfSend(application, recipient, isSms)) { Log.i(TAG, "SMS or local self-send. Skipping pre-upload."); - result.postValue(MediaSendActivityResult.forTraditionalSend(updatedMedia, trimmedBody, transport, isViewOnce(), mentions)); + result.postValue(MediaSendActivityResult.forTraditionalSend(updatedMedia, trimmedBody, transport, isViewOnce(), trimmedMentions)); return; } @@ -494,12 +495,12 @@ class MediaSendViewModel extends ViewModel { uploadRepository.updateDisplayOrder(updatedMedia); uploadRepository.getPreUploadResults(uploadResults -> { if (recipients.size() > 0) { - sendMessages(recipients, splitBody, uploadResults, mentions); + sendMessages(recipients, splitBody, uploadResults, trimmedMentions); uploadRepository.deleteAbandonedAttachments(); } Util.cancelRunnableOnMain(dialogRunnable); - result.postValue(MediaSendActivityResult.forPreUpload(uploadResults, splitBody, transport, isViewOnce(), mentions)); + result.postValue(MediaSendActivityResult.forPreUpload(uploadResults, splitBody, transport, isViewOnce(), trimmedMentions)); }); });