From f80e7e169b3d5d3945ea4a4d06ad1f390cba75e7 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Thu, 27 Aug 2020 10:49:15 +1000 Subject: [PATCH 1/2] use server timestamp to sort the open group messages --- .../securesms/database/MmsDatabase.java | 25 ++++++++++++++----- .../securesms/database/SmsDatabase.java | 16 +++++++++--- .../securesms/jobs/PushDecryptJob.java | 13 ++++++++-- .../securesms/loki/api/PublicChatPoller.kt | 2 +- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index 5e9ff400aa..ba2c74da47 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -816,7 +816,8 @@ public class MmsDatabase extends MessagingDatabase { private Optional insertMessageInbox(IncomingMediaMessage retrieved, String contentLocation, - long threadId, long mailbox) + long threadId, long mailbox, + long serverTimestamp) throws MmsException { if (threadId == -1 || retrieved.isGroupMessage()) { @@ -839,7 +840,13 @@ public class MmsDatabase extends MessagingDatabase { contentValues.put(THREAD_ID, threadId); contentValues.put(CONTENT_LOCATION, contentLocation); contentValues.put(STATUS, Status.DOWNLOAD_INITIALIZED); - contentValues.put(DATE_RECEIVED, retrieved.getSentTimeMillis()); // Loki - This is important due to how we handle GIFs + // If the messages are from open groups, there will be a serverTimestamp, + // we use current time like a sortId of iOS as the receive time. + // Since the messages has been sorted by server timestamp before they are processed, + // the order here by actual receiving time should be correct. + long receiveTimestamp = System.currentTimeMillis(); + if (serverTimestamp == 0) { receiveTimestamp = retrieved.getSentTimeMillis(); } + contentValues.put(DATE_RECEIVED, receiveTimestamp); // Loki - This is important due to how we handle GIFs contentValues.put(PART_COUNT, retrieved.getAttachments().size()); contentValues.put(SUBSCRIPTION_ID, retrieved.getSubscriptionId()); contentValues.put(EXPIRES_IN, retrieved.getExpiresIn()); @@ -893,11 +900,11 @@ public class MmsDatabase extends MessagingDatabase { type |= Types.EXPIRATION_TIMER_UPDATE_BIT; } - return insertMessageInbox(retrieved, contentLocation, threadId, type); + return insertMessageInbox(retrieved, contentLocation, threadId, type, 0); } - public Optional insertSecureDecryptedMessageInbox(IncomingMediaMessage retrieved, long threadId) - throws MmsException + public Optional insertSecureDecryptedMessageInbox(IncomingMediaMessage retrieved, long threadId, long serverTimestamp) + throws MmsException { long type = Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT; @@ -909,7 +916,13 @@ public class MmsDatabase extends MessagingDatabase { type |= Types.EXPIRATION_TIMER_UPDATE_BIT; } - return insertMessageInbox(retrieved, "", threadId, type); + return insertMessageInbox(retrieved, "", threadId, type, 0); + } + + public Optional insertSecureDecryptedMessageInbox(IncomingMediaMessage retrieved, long threadId) + throws MmsException + { + return insertSecureDecryptedMessageInbox(retrieved, threadId, 0); } public Pair insertMessageInbox(@NonNull NotificationInd notification, int subscriptionId) { diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java index 1727d5e86d..d75b5346b1 100644 --- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -580,7 +580,7 @@ public class SmsDatabase extends MessagingDatabase { return new Pair<>(messageId, threadId); } - protected Optional insertMessageInbox(IncomingTextMessage message, long type) { + protected Optional insertMessageInbox(IncomingTextMessage message, long type, long serverTimestamp) { if (message.isJoined()) { type = (type & (Types.TOTAL_MASK - Types.BASE_TYPE_MASK)) | Types.JOINED_TYPE; } else if (message.isPreKeyBundle()) { @@ -625,7 +625,13 @@ public class SmsDatabase extends MessagingDatabase { ContentValues values = new ContentValues(6); values.put(ADDRESS, message.getSender().serialize()); values.put(ADDRESS_DEVICE_ID, message.getSenderDeviceId()); - values.put(DATE_RECEIVED, message.getSentTimestampMillis()); // Loki - This is important due to how we handle GIFs + // If the messages are from open groups, there will be a serverTimestamp, + // we use current time like a sortId of iOS as the receive time. + // Since the messages has been sorted by server timestamp before they are processed, + // the order here by actual receiving time should be correct. + long receiveTimestamp = System.currentTimeMillis(); + if (serverTimestamp == 0) { receiveTimestamp = message.getSentTimestampMillis(); } + values.put(DATE_RECEIVED, receiveTimestamp); // Loki - This is important due to how we handle GIFs values.put(DATE_SENT, message.getSentTimestampMillis()); values.put(PROTOCOL, message.getProtocol()); values.put(READ, unread ? 0 : 1); @@ -672,7 +678,11 @@ public class SmsDatabase extends MessagingDatabase { } public Optional insertMessageInbox(IncomingTextMessage message) { - return insertMessageInbox(message, Types.BASE_INBOX_TYPE); + return insertMessageInbox(message, Types.BASE_INBOX_TYPE, 0); + } + + public Optional insertMessageInbox(IncomingTextMessage message, long serverTimestamp) { + return insertMessageInbox(message, Types.BASE_INBOX_TYPE, serverTimestamp); } public long insertMessageOutbox(long threadId, OutgoingTextMessage message, diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 402bf50c31..28ec14dfdf 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -755,7 +755,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType { Optional insertResult; try { - insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1); + if (message.isGroupMessage()) { + insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1, content.getTimestamp()); + } else { + insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1); + } if (insertResult.isPresent()) { List allAttachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(insertResult.get().getMessageId()); @@ -952,7 +956,12 @@ public class PushDecryptJob extends BaseJob implements InjectableType { if (textMessage.getMessageBody().length() == 0) { return; } // Insert the message into the database - Optional insertResult = database.insertMessageInbox(textMessage); + Optional insertResult; + if (message.isGroupMessage()) { + insertResult = database.insertMessageInbox(textMessage, content.getTimestamp()); + } else { + insertResult = database.insertMessageInbox(textMessage); + } if (insertResult.isPresent()) { threadId = insertResult.get().getThreadId(); diff --git a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt index 7aaf2322f7..28aa5f93f3 100644 --- a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt @@ -166,7 +166,7 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh } val senderHexEncodedPublicKey = masterHexEncodedPublicKey ?: message.senderPublicKey val serviceDataMessage = getDataMessage(message) - val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false, false) + val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.serverTimestamp, false, false) if (serviceDataMessage.quote.isPresent || (serviceDataMessage.attachments.isPresent && serviceDataMessage.attachments.get().size > 0) || serviceDataMessage.previews.isPresent) { PushDecryptJob(context).handleMediaMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID)) } else { From 3b84448d387d5c1cb34a0634bf4d7ecb08546ff8 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Thu, 27 Aug 2020 14:25:13 +1000 Subject: [PATCH 2/2] fix issues --- .../securesms/conversation/ConversationAdapter.java | 4 +++- src/org/thoughtcrime/securesms/database/MmsDatabase.java | 2 +- src/org/thoughtcrime/securesms/database/SmsDatabase.java | 2 +- .../thoughtcrime/securesms/database/model/MessageRecord.java | 3 +++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationAdapter.java b/src/org/thoughtcrime/securesms/conversation/ConversationAdapter.java index 0182fde11e..64e7365b1d 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationAdapter.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationAdapter.java @@ -426,7 +426,9 @@ public class ConversationAdapter @Override public void onBindHeaderViewHolder(HeaderViewHolder viewHolder, int position) { MessageRecord messageRecord = getRecordForPositionOrThrow(position); - viewHolder.setText(DateUtils.getRelativeDate(getContext(), locale, messageRecord.getDateReceived())); + long timestamp = messageRecord.getDateReceived(); + if (recipient.getAddress().isOpenGroup()) { timestamp = messageRecord.getTimestamp(); } + viewHolder.setText(DateUtils.getRelativeDate(getContext(), locale, timestamp)); } public void onBindLastSeenViewHolder(HeaderViewHolder viewHolder, int position) { diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index ba2c74da47..4ef30d33eb 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -844,7 +844,7 @@ public class MmsDatabase extends MessagingDatabase { // we use current time like a sortId of iOS as the receive time. // Since the messages has been sorted by server timestamp before they are processed, // the order here by actual receiving time should be correct. - long receiveTimestamp = System.currentTimeMillis(); + long receiveTimestamp = serverTimestamp; if (serverTimestamp == 0) { receiveTimestamp = retrieved.getSentTimeMillis(); } contentValues.put(DATE_RECEIVED, receiveTimestamp); // Loki - This is important due to how we handle GIFs contentValues.put(PART_COUNT, retrieved.getAttachments().size()); diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java index d75b5346b1..aa9aeabdaf 100644 --- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -629,7 +629,7 @@ public class SmsDatabase extends MessagingDatabase { // we use current time like a sortId of iOS as the receive time. // Since the messages has been sorted by server timestamp before they are processed, // the order here by actual receiving time should be correct. - long receiveTimestamp = System.currentTimeMillis(); + long receiveTimestamp = serverTimestamp; if (serverTimestamp == 0) { receiveTimestamp = message.getSentTimestampMillis(); } values.put(DATE_RECEIVED, receiveTimestamp); // Loki - This is important due to how we handle GIFs values.put(DATE_SENT, message.getSentTimestampMillis()); diff --git a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java index 2e54b9d65e..effea38c60 100644 --- a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -139,6 +139,9 @@ public abstract class MessageRecord extends DisplayRecord { if (isPush() && getDateSent() < getDateReceived()) { return getDateSent(); } + if (getRecipient().getAddress().isOpenGroup()) { + return getDateSent(); + } return getDateReceived(); }