From b517555a4580da93f8447b538063bff727f0e557 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Tue, 16 Feb 2021 15:24:21 +1100 Subject: [PATCH] timestamp & duplicated message --- .../securesms/database/MmsSmsDatabase.java | 8 ++++++++ .../securesms/database/Storage.kt | 20 ++++++++++++++----- .../loki/protocol/SessionMetaProtocol.kt | 8 ++++++++ .../libsession/messaging/StorageProtocol.kt | 3 ++- .../sending_receiving/MessageReceiver.kt | 2 +- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index a27ae0c691..2deacb7fa7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -78,6 +78,14 @@ public class MmsSmsDatabase extends Database { super(context, databaseHelper); } + public @Nullable MessageRecord getMessageForTimestamp(long timestamp) { + MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context); + try (Cursor cursor = queryTables(PROJECTION, MmsSmsColumns.NORMALIZED_DATE_SENT + " = " + timestamp, null, null)) { + MmsSmsDatabase.Reader reader = db.readerFor(cursor); + return reader.getNext(); + } + } + public @Nullable MessageRecord getMessageFor(long messageId) { MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 60d5ca84b2..7d39d5032f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -33,6 +33,7 @@ import org.session.libsignal.utilities.logging.Log import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase +import org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities import org.thoughtcrime.securesms.loki.utilities.get import org.thoughtcrime.securesms.loki.utilities.getString @@ -279,6 +280,15 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, DatabaseFactory.getLokiAPIDatabase(context).removeLastDeletionServerID(group, server) } + override fun isMessageDuplicated(timestamp: Long, sender: String): Boolean { + val database = DatabaseFactory.getMmsSmsDatabase(context) + return if (sender.isEmpty()) { + database.getMessageForTimestamp(timestamp) != null + } else { + database.getMessageFor(timestamp, sender) != null + } + } + override fun setUserCount(group: Long, server: String, newValue: Int) { DatabaseFactory.getLokiAPIDatabase(context).setUserCount(group, server, newValue) } @@ -300,16 +310,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getReceivedMessageTimestamps(): Set { - TODO("Not yet implemented") + return SessionMetaProtocol.getTimestamps() } override fun addReceivedMessageTimestamp(timestamp: Long) { - TODO("Not yet implemented") + SessionMetaProtocol.addTimestamp(timestamp) } - override fun removeReceivedMessageTimestamps(timestamps: Set) { - TODO("Not yet implemented") - } +// override fun removeReceivedMessageTimestamps(timestamps: Set) { +// TODO("Not yet implemented") +// } override fun getMessageIdInDatabase(timestamp: Long, author: String): Long? { val database = DatabaseFactory.getMmsSmsDatabase(context) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt index 03eaf970c0..7e5125e58f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt @@ -21,6 +21,14 @@ object SessionMetaProtocol { timestamps.remove(timestamp) } + fun getTimestamps(): Set { + return timestamps + } + + fun addTimestamp(timestamp: Long) { + timestamps.add(timestamp) + } + @JvmStatic fun shouldIgnoreMessage(timestamp: Long): Boolean { val shouldIgnoreMessage = timestamps.contains(timestamp) diff --git a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt index 484cb61c72..e3062f73ee 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt @@ -86,9 +86,10 @@ interface StorageProtocol { fun removeLastDeletionServerID(group: Long, server: String) // Message Handling + fun isMessageDuplicated(timestamp: Long, sender: String): Boolean fun getReceivedMessageTimestamps(): Set fun addReceivedMessageTimestamp(timestamp: Long) - fun removeReceivedMessageTimestamps(timestamps: Set) +// fun removeReceivedMessageTimestamps(timestamps: Set) // Returns the IDs of the saved attachments. fun persistAttachments(messageId: Long, attachments: List): List diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt index 89ed36d909..6ec3d4e1a3 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt @@ -50,7 +50,7 @@ object MessageReceiver { // If the message failed to process the first time around we retry it later (if the error is retryable). In this case the timestamp // will already be in the database but we don't want to treat the message as a duplicate. The isRetry flag is a simple workaround // for this issue. - if (storage.getReceivedMessageTimestamps().contains(envelope.timestamp) && !isRetry) throw Error.DuplicateMessage + if (storage.isMessageDuplicated(envelope.timestamp, envelope.source) && !isRetry) throw Error.DuplicateMessage storage.addReceivedMessageTimestamp(envelope.timestamp) // Decrypt the contents val ciphertext = envelope.content ?: throw Error.NoData