Fix expiry start

This commit is contained in:
charles 2022-12-21 15:48:56 +11:00
parent 8f99b5aa11
commit 2228bfc8f2
8 changed files with 46 additions and 24 deletions

View File

@ -15,6 +15,7 @@ import kotlinx.coroutines.launch
import org.session.libsession.messaging.messages.ExpirationConfiguration import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
@ -108,7 +109,7 @@ class ExpirationSettingsViewModel(
return@launch return@launch
} }
val expiryChangeTimestampMs = System.currentTimeMillis() val expiryChangeTimestampMs = System.currentTimeMillis() + SnodeAPI.clockOffset
storage.setExpirationConfiguration(ExpirationConfiguration(threadId, expirationTimer, expiryType, expiryChangeTimestampMs)) storage.setExpirationConfiguration(ExpirationConfiguration(threadId, expirationTimer, expiryType, expiryChangeTimestampMs))
val message = ExpirationTimerUpdate(expirationTimer) val message = ExpirationTimerUpdate(expirationTimer)

View File

@ -3,13 +3,21 @@ package org.thoughtcrime.securesms.conversation.v2
import android.Manifest import android.Manifest
import android.animation.FloatEvaluator import android.animation.FloatEvaluator
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.content.* import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.res.Resources import android.content.res.Resources
import android.database.Cursor import android.database.Cursor
import android.graphics.Rect import android.graphics.Rect
import android.graphics.Typeface import android.graphics.Typeface
import android.net.Uri import android.net.Uri
import android.os.* import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore import android.provider.MediaStore
import android.text.TextUtils import android.text.TextUtils
import android.util.Pair import android.util.Pair
@ -58,8 +66,13 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
import org.session.libsession.messaging.utilities.SessionId import org.session.libsession.messaging.utilities.SessionId
import org.session.libsession.utilities.* import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.fromSerialized import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.MediaTypes
import org.session.libsession.utilities.Stub
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.concurrent.SimpleTask import org.session.libsession.utilities.concurrent.SimpleTask
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.recipients.Recipient.DisappearingState import org.session.libsession.utilities.recipients.Recipient.DisappearingState
@ -123,7 +136,14 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState
import org.thoughtcrime.securesms.mediasend.Media import org.thoughtcrime.securesms.mediasend.Media
import org.thoughtcrime.securesms.mediasend.MediaSendActivity import org.thoughtcrime.securesms.mediasend.MediaSendActivity
import org.thoughtcrime.securesms.mms.* import org.thoughtcrime.securesms.mms.AudioSlide
import org.thoughtcrime.securesms.mms.GifSlide
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.ImageSlide
import org.thoughtcrime.securesms.mms.MediaConstraints
import org.thoughtcrime.securesms.mms.Slide
import org.thoughtcrime.securesms.mms.SlideDeck
import org.thoughtcrime.securesms.mms.VideoSlide
import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.reactions.ReactionsDialogFragment import org.thoughtcrime.securesms.reactions.ReactionsDialogFragment
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiDialogFragment import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiDialogFragment
@ -1070,7 +1090,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
// Create the message // Create the message
val recipient = viewModel.recipient ?: return val recipient = viewModel.recipient ?: return
val reactionMessage = VisibleMessage() val reactionMessage = VisibleMessage()
val emojiTimestamp = System.currentTimeMillis() val emojiTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset
reactionMessage.sentTimestamp = emojiTimestamp reactionMessage.sentTimestamp = emojiTimestamp
val author = textSecurePreferences.getLocalNumber()!! val author = textSecurePreferences.getLocalNumber()!!
// Put the message in the database // Put the message in the database
@ -1103,7 +1123,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
private fun sendEmojiRemoval(emoji: String, originalMessage: MessageRecord) { private fun sendEmojiRemoval(emoji: String, originalMessage: MessageRecord) {
val recipient = viewModel.recipient ?: return val recipient = viewModel.recipient ?: return
val message = VisibleMessage() val message = VisibleMessage()
val emojiTimestamp = System.currentTimeMillis() val emojiTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset
message.sentTimestamp = emojiTimestamp message.sentTimestamp = emojiTimestamp
val author = textSecurePreferences.getLocalNumber()!! val author = textSecurePreferences.getLocalNumber()!!
reactionDb.deleteReaction(emoji, MessageId(originalMessage.id, originalMessage.isMms), author, false) reactionDb.deleteReaction(emoji, MessageId(originalMessage.id, originalMessage.isMms), author, false)
@ -1332,7 +1352,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
} }
// Create the message // Create the message
val message = VisibleMessage() val message = VisibleMessage()
message.sentTimestamp = System.currentTimeMillis() message.sentTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset
message.text = text message.text = text
val expiresInMillis = (viewModel.expirationConfiguration?.durationSeconds ?: 0) * 1000L val expiresInMillis = (viewModel.expirationConfiguration?.durationSeconds ?: 0) * 1000L
val outgoingTextMessage = OutgoingTextMessage.from(message, recipient, expiresInMillis) val outgoingTextMessage = OutgoingTextMessage.from(message, recipient, expiresInMillis)
@ -1356,7 +1376,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
val recipient = viewModel.recipient ?: return val recipient = viewModel.recipient ?: return
processMessageRequestApproval() processMessageRequestApproval()
// Create the message // Create the message
val sentTimestampMs = System.currentTimeMillis() val sentTimestampMs = System.currentTimeMillis() + SnodeAPI.clockOffset
val message = VisibleMessage() val message = VisibleMessage()
message.sentTimestamp = sentTimestampMs message.sentTimestamp = sentTimestampMs
message.text = body message.text = body
@ -1375,7 +1395,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
} }
val expiresInMs = (viewModel.expirationConfiguration?.durationSeconds ?: 0) * 1000L val expiresInMs = (viewModel.expirationConfiguration?.durationSeconds ?: 0) * 1000L
val expireStartedAtMs = if (viewModel.expirationConfiguration?.expirationType == ExpirationType.DELETE_AFTER_SEND) { val expireStartedAtMs = if (viewModel.expirationConfiguration?.expirationType == ExpirationType.DELETE_AFTER_SEND) {
sentTimestampMs + expiresInMs sentTimestampMs
} else 0 } else 0
val outgoingTextMessage = OutgoingMediaMessage.from(message, recipient, attachments, localQuote, linkPreview, expiresInMs, expireStartedAtMs) val outgoingTextMessage = OutgoingMediaMessage.from(message, recipient, attachments, localQuote, linkPreview, expiresInMs, expireStartedAtMs)
// Clear the input bar // Clear the input bar

View File

@ -161,7 +161,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
val expirationConfig = getExpirationConfiguration(message.threadID ?: -1) val expirationConfig = getExpirationConfiguration(message.threadID ?: -1)
val expiresIn = expirationConfig?.durationSeconds ?: 0 val expiresIn = expirationConfig?.durationSeconds ?: 0
val expireStartedAt = if (expirationConfig?.expirationType == ExpirationType.DELETE_AFTER_SEND) { val expireStartedAt = if (expirationConfig?.expirationType == ExpirationType.DELETE_AFTER_SEND) {
message.sentTimestamp!! + (expiresIn * 1000L) message.sentTimestamp!!
} else 0 } else 0
if (message.isMediaMessage() || attachments.isNotEmpty()) { if (message.isMediaMessage() || attachments.isNotEmpty()) {
val quote: Optional<QuoteModel> = if (quotes != null) Optional.of(quotes) else Optional.absent() val quote: Optional<QuoteModel> = if (quotes != null) Optional.of(quotes) else Optional.absent()

View File

@ -106,7 +106,7 @@ class DefaultConversationRepository @Inject constructor(
val openGroup = lokiThreadDb.getOpenGroupChat(threadId) ?: return val openGroup = lokiThreadDb.getOpenGroupChat(threadId) ?: return
for (contact in contacts) { for (contact in contacts) {
val message = VisibleMessage() val message = VisibleMessage()
message.sentTimestamp = System.currentTimeMillis() message.sentTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset
val openGroupInvitation = OpenGroupInvitation() val openGroupInvitation = OpenGroupInvitation()
openGroupInvitation.name = openGroup.name openGroupInvitation.name = openGroup.name
openGroupInvitation.url = openGroup.joinURL openGroupInvitation.url = openGroup.joinURL

View File

@ -72,7 +72,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
String userPublicKey = TextSecurePreferences.getLocalNumber(context); String userPublicKey = TextSecurePreferences.getLocalNumber(context);
String senderPublicKey = message.getSender(); String senderPublicKey = message.getSender();
long expireStartedAt = ExpirationType.DELETE_AFTER_SEND_VALUE != expiryType long expireStartedAt = ExpirationType.DELETE_AFTER_SEND_VALUE != expiryType
? 0 : message.getSentTimestamp() + (message.getDuration() * 1000L); ? 0 : message.getSentTimestamp();
// Notify the user // Notify the user
if (senderPublicKey == null || userPublicKey.equals(senderPublicKey)) { if (senderPublicKey == null || userPublicKey.equals(senderPublicKey)) {
@ -161,7 +161,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
} else { } else {
smsDatabase.markExpireStarted(messageRecord.getId(), expireStartedAt); smsDatabase.markExpireStarted(messageRecord.getId(), expireStartedAt);
} }
scheduleDeletion(messageRecord.getId(), mms, config.getDurationSeconds() * 1000L); scheduleDeletion(messageRecord.getId(), mms, expireStartedAt, config.getDurationSeconds() * 1000L);
} }
} }

View File

@ -79,7 +79,7 @@ object MessageSender {
val userPublicKey = storage.getUserPublicKey() val userPublicKey = storage.getUserPublicKey()
// Set the timestamp, sender and recipient // Set the timestamp, sender and recipient
if (message.sentTimestamp == null) { if (message.sentTimestamp == null) {
message.sentTimestamp = System.currentTimeMillis() // Visible messages will already have their sent timestamp set message.sentTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset // Visible messages will already have their sent timestamp set
} }
val messageSendTime = System.currentTimeMillis() val messageSendTime = System.currentTimeMillis()
@ -238,7 +238,7 @@ object MessageSender {
val deferred = deferred<Unit, Exception>() val deferred = deferred<Unit, Exception>()
val storage = MessagingModuleConfiguration.shared.storage val storage = MessagingModuleConfiguration.shared.storage
if (message.sentTimestamp == null) { if (message.sentTimestamp == null) {
message.sentTimestamp = System.currentTimeMillis() message.sentTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset
} }
val userEdKeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair()!! val userEdKeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair()!!
var serverCapabilities = listOf<String>() var serverCapabilities = listOf<String>()

View File

@ -10,6 +10,7 @@ import org.session.libsession.messaging.messages.control.ClosedGroupControlMessa
import org.session.libsession.messaging.sending_receiving.MessageSender.Error import org.session.libsession.messaging.sending_receiving.MessageSender.Error
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2 import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.fromSerialized import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.GroupUtil
@ -53,7 +54,7 @@ fun MessageSender.create(name: String, members: Collection<String>): Promise<Str
storage.setProfileSharing(Address.fromSerialized(groupID), true) storage.setProfileSharing(Address.fromSerialized(groupID), true)
// Send a closed group update message to all members individually // Send a closed group update message to all members individually
val closedGroupUpdateKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, 0) val closedGroupUpdateKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, 0)
val sentTime = System.currentTimeMillis() val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
for (member in members) { for (member in members) {
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind) val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind)
closedGroupControlMessage.sentTimestamp = sentTime closedGroupControlMessage.sentTimestamp = sentTime
@ -113,7 +114,7 @@ fun MessageSender.setName(groupPublicKey: String, newName: String) {
val admins = group.admins.map { it.serialize() } val admins = group.admins.map { it.serialize() }
// Send the update to the group // Send the update to the group
val kind = ClosedGroupControlMessage.Kind.NameChange(newName) val kind = ClosedGroupControlMessage.Kind.NameChange(newName)
val sentTime = System.currentTimeMillis() val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
val closedGroupControlMessage = ClosedGroupControlMessage(kind) val closedGroupControlMessage = ClosedGroupControlMessage(kind)
closedGroupControlMessage.sentTimestamp = sentTime closedGroupControlMessage.sentTimestamp = sentTime
send(closedGroupControlMessage, Address.fromSerialized(groupID)) send(closedGroupControlMessage, Address.fromSerialized(groupID))
@ -153,7 +154,7 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
val name = group.title val name = group.title
// Send the update to the group // Send the update to the group
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersAdded(newMembersAsData) val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersAdded(newMembersAsData)
val sentTime = System.currentTimeMillis() val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind) val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
closedGroupControlMessage.sentTimestamp = sentTime closedGroupControlMessage.sentTimestamp = sentTime
send(closedGroupControlMessage, Address.fromSerialized(groupID)) send(closedGroupControlMessage, Address.fromSerialized(groupID))
@ -167,7 +168,7 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
// updates from before that timestamp. By setting the timestamp of the message below to a value // updates from before that timestamp. By setting the timestamp of the message below to a value
// greater than that of the `MembersAdded` message, we ensure that newly added members ignore // greater than that of the `MembersAdded` message, we ensure that newly added members ignore
// the `MembersAdded` message. // the `MembersAdded` message.
closedGroupControlMessage.sentTimestamp = System.currentTimeMillis() closedGroupControlMessage.sentTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset
send(closedGroupControlMessage, Address.fromSerialized(member)) send(closedGroupControlMessage, Address.fromSerialized(member))
} }
// Notify the user // Notify the user
@ -208,7 +209,7 @@ fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List<St
val name = group.title val name = group.title
// Send the update to the group // Send the update to the group
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersRemoved(removeMembersAsData) val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersRemoved(removeMembersAsData)
val sentTime = System.currentTimeMillis() val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind) val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
closedGroupControlMessage.sentTimestamp = sentTime closedGroupControlMessage.sentTimestamp = sentTime
send(closedGroupControlMessage, Address.fromSerialized(groupID)) send(closedGroupControlMessage, Address.fromSerialized(groupID))
@ -239,7 +240,7 @@ fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Pro
val name = group.title val name = group.title
// Send the update to the group // Send the update to the group
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.MemberLeft()) val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.MemberLeft())
val sentTime = System.currentTimeMillis() val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
closedGroupControlMessage.sentTimestamp = sentTime closedGroupControlMessage.sentTimestamp = sentTime
storage.setActive(groupID, false) storage.setActive(groupID, false)
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success { sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success {
@ -298,7 +299,7 @@ fun MessageSender.sendEncryptionKeyPair(groupPublicKey: String, newKeyPair: ECKe
ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext)) ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
} }
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), wrappers) val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), wrappers)
val sentTime = System.currentTimeMillis() val sentTime = System.currentTimeMillis() + SnodeAPI.clockOffset
val closedGroupControlMessage = ClosedGroupControlMessage(kind) val closedGroupControlMessage = ClosedGroupControlMessage(kind)
closedGroupControlMessage.sentTimestamp = sentTime closedGroupControlMessage.sentTimestamp = sentTime
return if (force) { return if (force) {

View File

@ -55,7 +55,7 @@ object SnodeAPI {
* The offset between the user's clock and the Service Node's clock. Used in cases where the * The offset between the user's clock and the Service Node's clock. Used in cases where the
* user's clock is incorrect. * user's clock is incorrect.
*/ */
internal var clockOffset = 0L var clockOffset = 0L
internal var forkInfo by observable(database.getForkInfo()) { _, oldValue, newValue -> internal var forkInfo by observable(database.getForkInfo()) { _, oldValue, newValue ->
if (newValue > oldValue) { if (newValue > oldValue) {
Log.d("Loki", "Setting new fork info new: $newValue, old: $oldValue") Log.d("Loki", "Setting new fork info new: $newValue, old: $oldValue")