From 3a479d7eef4c61d58edc8f7be940ebdf1b225ba8 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Sun, 7 Jun 2020 14:46:03 -0400 Subject: [PATCH] Reduce database notifications for disappearing conversations. --- .../securesms/database/MessagingDatabase.java | 2 + .../securesms/database/MmsDatabase.java | 37 +++++++++++++---- .../securesms/database/SmsDatabase.java | 29 +++++++++++--- .../notifications/MarkReadReceiver.java | 40 ++++++++++++++----- 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java index ab99fa85a6..6cc0fed685 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java @@ -27,6 +27,7 @@ import org.whispersystems.libsignal.util.guava.Optional; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -46,6 +47,7 @@ public abstract class MessagingDatabase extends Database implements MmsSmsColumn public abstract void markExpireStarted(long messageId); public abstract void markExpireStarted(long messageId, long startTime); + public abstract void markExpireStarted(Collection messageId, long startTime); public abstract void markAsSent(long messageId, boolean secure); public abstract void markUnidentified(long messageId, boolean unidentified); 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 6b6b6c7142..a5be861ae3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -76,6 +76,7 @@ import org.whispersystems.libsignal.util.guava.Optional; import java.io.Closeable; import java.io.IOException; import java.security.SecureRandom; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -570,19 +571,39 @@ public class MmsDatabase extends MessagingDatabase { } @Override - public void markExpireStarted(long messageId) { - markExpireStarted(messageId, System.currentTimeMillis()); + public void markExpireStarted(long id) { + markExpireStarted(id, System.currentTimeMillis()); } @Override - public void markExpireStarted(long messageId, long startedTimestamp) { - ContentValues contentValues = new ContentValues(); - contentValues.put(EXPIRE_STARTED, startedTimestamp); + public void markExpireStarted(long id, long startedTimestamp) { + markExpireStarted(Collections.singleton(id), startedTimestamp); + } - SQLiteDatabase db = databaseHelper.getWritableDatabase(); - db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(messageId)}); + @Override + public void markExpireStarted(Collection ids, long startedAtTimestamp) { + SQLiteDatabase db = databaseHelper.getWritableDatabase(); + long threadId = -1; - long threadId = getThreadIdForMessage(messageId); + db.beginTransaction(); + try { + for (long id : ids) { + ContentValues contentValues = new ContentValues(); + contentValues.put(EXPIRE_STARTED, startedAtTimestamp); + + db.update(TABLE_NAME, contentValues, ID_WHERE, new String[]{String.valueOf(id)}); + + if (threadId < 0) { + threadId = getThreadIdForMessage(id); + } + } + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + + DatabaseFactory.getThreadDatabase(context).update(threadId, false); notifyConversationListeners(threadId); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index d60b325cfa..d5462b2d2a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -51,6 +51,7 @@ import org.whispersystems.libsignal.util.guava.Optional; import java.io.IOException; import java.security.SecureRandom; +import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -355,13 +356,31 @@ public class SmsDatabase extends MessagingDatabase { @Override public void markExpireStarted(long id, long startedAtTimestamp) { - ContentValues contentValues = new ContentValues(); - contentValues.put(EXPIRE_STARTED, startedAtTimestamp); + markExpireStarted(Collections.singleton(id), startedAtTimestamp); + } - SQLiteDatabase db = databaseHelper.getWritableDatabase(); - db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(id)}); + @Override + public void markExpireStarted(Collection ids, long startedAtTimestamp) { + SQLiteDatabase db = databaseHelper.getWritableDatabase(); + long threadId = -1; - long threadId = getThreadIdForMessage(id); + db.beginTransaction(); + try { + for (long id : ids) { + ContentValues contentValues = new ContentValues(); + contentValues.put(EXPIRE_STARTED, startedAtTimestamp); + + db.update(TABLE_NAME, contentValues, ID_WHERE, new String[]{String.valueOf(id)}); + + if (threadId < 0) { + threadId = getThreadIdForMessage(id); + } + } + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } DatabaseFactory.getThreadDatabase(context).update(threadId, false); notifyConversationListeners(threadId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java index cbc4f6777a..d0cc410d7e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java @@ -70,12 +70,21 @@ public class MarkReadReceiver extends BroadcastReceiver { public static void process(@NonNull Context context, @NonNull List markedReadMessages) { if (markedReadMessages.isEmpty()) return; - List syncMessageIds = new LinkedList<>(); + List syncMessageIds = Stream.of(markedReadMessages) + .map(MarkedMessageInfo::getSyncMessageId) + .toList(); + List mmsExpirationInfo = Stream.of(markedReadMessages) + .map(MarkedMessageInfo::getExpirationInfo) + .filter(ExpirationInfo::isMms) + .filter(info -> info.getExpiresIn() > 0 && info.getExpireStarted() <= 0) + .toList(); + List smsExpirationInfo = Stream.of(markedReadMessages) + .map(MarkedMessageInfo::getExpirationInfo) + .filterNot(ExpirationInfo::isMms) + .filter(info -> info.getExpiresIn() > 0 && info.getExpireStarted() <= 0) + .toList(); - for (MarkedMessageInfo messageInfo : markedReadMessages) { - scheduleDeletion(context, messageInfo.getExpirationInfo()); - syncMessageIds.add(messageInfo.getSyncMessageId()); - } + scheduleDeletion(context, smsExpirationInfo, mmsExpirationInfo); ApplicationDependencies.getJobManager().add(new MultiDeviceReadUpdateJob(syncMessageIds)); @@ -95,14 +104,23 @@ public class MarkReadReceiver extends BroadcastReceiver { }); } - private static void scheduleDeletion(Context context, ExpirationInfo expirationInfo) { - if (expirationInfo.getExpiresIn() > 0 && expirationInfo.getExpireStarted() <= 0) { + private static void scheduleDeletion(@NonNull Context context, + @NonNull List smsExpirationInfo, + @NonNull List mmsExpirationInfo) + { + if (smsExpirationInfo.size() > 0) { + DatabaseFactory.getSmsDatabase(context).markExpireStarted(Stream.of(smsExpirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis()); + } + + if (mmsExpirationInfo.size() > 0) { + DatabaseFactory.getMmsDatabase(context).markExpireStarted(Stream.of(mmsExpirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis()); + } + + if (smsExpirationInfo.size() + mmsExpirationInfo.size() > 0) { ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager(); - if (expirationInfo.isMms()) DatabaseFactory.getMmsDatabase(context).markExpireStarted(expirationInfo.getId()); - else DatabaseFactory.getSmsDatabase(context).markExpireStarted(expirationInfo.getId()); - - expirationManager.scheduleDeletion(expirationInfo.getId(), expirationInfo.isMms(), expirationInfo.getExpiresIn()); + Stream.concat(Stream.of(smsExpirationInfo), Stream.of(mmsExpirationInfo)) + .forEach(info -> expirationManager.scheduleDeletion(info.getId(), info.isMms(), info.getExpiresIn())); } } }