mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
Start expiration at end of handling each message type treating call and extraction as DaR
This commit is contained in:
parent
e2e5a36f51
commit
848dbd2eb0
@ -37,7 +37,7 @@ class DisappearingMessages @Inject constructor(
|
|||||||
sentTimestamp = expiryChangeTimestampMs
|
sentTimestamp = expiryChangeTimestampMs
|
||||||
}
|
}
|
||||||
|
|
||||||
messageExpirationManager.setExpirationTimer(message)
|
messageExpirationManager.insertExpirationTimerMessage(message)
|
||||||
MessageSender.send(message, address)
|
MessageSender.send(message, address)
|
||||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
|
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,6 @@ import kotlinx.coroutines.launch
|
|||||||
import network.loki.messenger.BuildConfig
|
import network.loki.messenger.BuildConfig
|
||||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||||
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.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.thoughtcrime.securesms.conversation.disappearingmessages.ui.ExpiryCallbacks
|
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.ExpiryCallbacks
|
||||||
@ -30,13 +27,13 @@ import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.toUiState
|
|||||||
import org.thoughtcrime.securesms.database.GroupDatabase
|
import org.thoughtcrime.securesms.database.GroupDatabase
|
||||||
import org.thoughtcrime.securesms.database.Storage
|
import org.thoughtcrime.securesms.database.Storage
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase
|
import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
|
||||||
|
|
||||||
class DisappearingMessagesViewModel(
|
class DisappearingMessagesViewModel(
|
||||||
private val threadId: Long,
|
private val threadId: Long,
|
||||||
private val application: Application,
|
private val application: Application,
|
||||||
private val textSecurePreferences: TextSecurePreferences,
|
private val textSecurePreferences: TextSecurePreferences,
|
||||||
private val messageExpirationManager: MessageExpirationManagerProtocol,
|
private val messageExpirationManager: MessageExpirationManagerProtocol,
|
||||||
|
private val disappearingMessages: DisappearingMessages,
|
||||||
private val threadDb: ThreadDatabase,
|
private val threadDb: ThreadDatabase,
|
||||||
private val groupDb: GroupDatabase,
|
private val groupDb: GroupDatabase,
|
||||||
private val storage: Storage,
|
private val storage: Storage,
|
||||||
@ -90,20 +87,7 @@ class DisappearingMessagesViewModel(
|
|||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
val expiryChangeTimestampMs = SnodeAPI.nowWithOffset
|
disappearingMessages.set(threadId, address, mode)
|
||||||
storage.setExpirationConfiguration(ExpirationConfiguration(threadId, mode, expiryChangeTimestampMs))
|
|
||||||
|
|
||||||
val message = ExpirationTimerUpdate().apply {
|
|
||||||
expiryMode = mode
|
|
||||||
sender = textSecurePreferences.getLocalNumber()
|
|
||||||
isSenderSelf = true
|
|
||||||
recipient = address.serialize()
|
|
||||||
sentTimestamp = expiryChangeTimestampMs
|
|
||||||
}
|
|
||||||
messageExpirationManager.setExpirationTimer(message)
|
|
||||||
MessageSender.send(message, address)
|
|
||||||
|
|
||||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(application)
|
|
||||||
|
|
||||||
_event.send(Event.SUCCESS)
|
_event.send(Event.SUCCESS)
|
||||||
}
|
}
|
||||||
@ -121,6 +105,7 @@ class DisappearingMessagesViewModel(
|
|||||||
private val application: Application,
|
private val application: Application,
|
||||||
private val textSecurePreferences: TextSecurePreferences,
|
private val textSecurePreferences: TextSecurePreferences,
|
||||||
private val messageExpirationManager: MessageExpirationManagerProtocol,
|
private val messageExpirationManager: MessageExpirationManagerProtocol,
|
||||||
|
private val disappearingMessages: DisappearingMessages,
|
||||||
private val threadDb: ThreadDatabase,
|
private val threadDb: ThreadDatabase,
|
||||||
private val groupDb: GroupDatabase,
|
private val groupDb: GroupDatabase,
|
||||||
private val storage: Storage
|
private val storage: Storage
|
||||||
@ -131,6 +116,7 @@ class DisappearingMessagesViewModel(
|
|||||||
application,
|
application,
|
||||||
textSecurePreferences,
|
textSecurePreferences,
|
||||||
messageExpirationManager,
|
messageExpirationManager,
|
||||||
|
disappearingMessages,
|
||||||
threadDb,
|
threadDb,
|
||||||
groupDb,
|
groupDb,
|
||||||
storage,
|
storage,
|
||||||
|
@ -253,6 +253,8 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markExpireStarted(long id, long startedAtTimestamp) {
|
public void markExpireStarted(long id, long startedAtTimestamp) {
|
||||||
|
Log.d(TAG, "markExpireStarted() called with: id = [" + id + "], startedAtTimestamp = [" + startedAtTimestamp + "]");
|
||||||
|
|
||||||
ContentValues contentValues = new ContentValues();
|
ContentValues contentValues = new ContentValues();
|
||||||
contentValues.put(EXPIRE_STARTED, startedAtTimestamp);
|
contentValues.put(EXPIRE_STARTED, startedAtTimestamp);
|
||||||
|
|
||||||
|
@ -56,10 +56,10 @@ class MarkReadReceiver : BroadcastReceiver() {
|
|||||||
context: Context,
|
context: Context,
|
||||||
markedReadMessages: List<MarkedMessageInfo>
|
markedReadMessages: List<MarkedMessageInfo>
|
||||||
) {
|
) {
|
||||||
if (markedReadMessages.isEmpty()) return
|
|
||||||
|
|
||||||
Log.d(TAG, "process() called with: markedReadMessages = $markedReadMessages")
|
Log.d(TAG, "process() called with: markedReadMessages = $markedReadMessages")
|
||||||
|
|
||||||
|
if (markedReadMessages.isEmpty()) return
|
||||||
|
|
||||||
sendReadReceipts(context, markedReadMessages)
|
sendReadReceipts(context, markedReadMessages)
|
||||||
|
|
||||||
markedReadMessages.forEach { scheduleDeletion(context, it.expirationInfo) }
|
markedReadMessages.forEach { scheduleDeletion(context, it.expirationInfo) }
|
||||||
|
@ -8,7 +8,6 @@ import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
|
|||||||
import org.session.libsession.messaging.messages.signal.IncomingMediaMessage
|
import org.session.libsession.messaging.messages.signal.IncomingMediaMessage
|
||||||
import org.session.libsession.messaging.messages.signal.OutgoingExpirationUpdateMessage
|
import org.session.libsession.messaging.messages.signal.OutgoingExpirationUpdateMessage
|
||||||
import org.session.libsession.snode.SnodeAPI.nowWithOffset
|
import org.session.libsession.snode.SnodeAPI.nowWithOffset
|
||||||
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.doubleEncodeGroupID
|
import org.session.libsession.utilities.GroupUtil.doubleEncodeGroupID
|
||||||
import org.session.libsession.utilities.GroupUtil.getDecodedGroupIDAsData
|
import org.session.libsession.utilities.GroupUtil.getDecodedGroupIDAsData
|
||||||
@ -21,7 +20,6 @@ import org.session.libsignal.utilities.guava.Optional
|
|||||||
import org.thoughtcrime.securesms.database.MmsDatabase
|
import org.thoughtcrime.securesms.database.MmsDatabase
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase
|
import org.thoughtcrime.securesms.database.MmsSmsDatabase
|
||||||
import org.thoughtcrime.securesms.database.SmsDatabase
|
import org.thoughtcrime.securesms.database.SmsDatabase
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
|
||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get
|
||||||
import org.thoughtcrime.securesms.mms.MmsException
|
import org.thoughtcrime.securesms.mms.MmsException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -149,15 +147,14 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setExpirationTimer(message: ExpirationTimerUpdate) {
|
override fun insertExpirationTimerMessage(message: ExpirationTimerUpdate) {
|
||||||
val expiryMode: ExpiryMode = message.expiryMode
|
val expiryMode: ExpiryMode = message.expiryMode
|
||||||
Log.d(TAG, "setExpirationTimer() called with: message = $message, expiryMode = $expiryMode")
|
Log.d(TAG, "setExpirationTimer() called with: message = $message, expiryMode = $expiryMode")
|
||||||
|
|
||||||
val userPublicKey = getLocalNumber(context)
|
val userPublicKey = getLocalNumber(context)
|
||||||
val senderPublicKey = message.sender
|
val senderPublicKey = message.sender
|
||||||
val sentTimestamp = if (message.sentTimestamp == null) 0 else message.sentTimestamp!!
|
val sentTimestamp = if (message.sentTimestamp == null) 0 else message.sentTimestamp!!
|
||||||
val expireStartedAt =
|
val expireStartedAt = if (expiryMode is AfterSend || message.isSenderSelf) sentTimestamp else 0
|
||||||
if (expiryMode is AfterSend || message.isSenderSelf) sentTimestamp else 0
|
|
||||||
|
|
||||||
// Notify the user
|
// Notify the user
|
||||||
if (senderPublicKey == null || userPublicKey == senderPublicKey) {
|
if (senderPublicKey == null || userPublicKey == senderPublicKey) {
|
||||||
@ -167,14 +164,13 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco
|
|||||||
insertIncomingExpirationTimerMessage(message, expireStartedAt)
|
insertIncomingExpirationTimerMessage(message, expireStartedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expiryMode is AfterSend && expiryMode.expirySeconds > 0 && message.sentTimestamp != null && senderPublicKey != null) {
|
startAnyExpiration(message)
|
||||||
startAnyExpiration(message.sentTimestamp!!, senderPublicKey, expireStartedAt)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long) {
|
override fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long) {
|
||||||
Log.d(TAG, "startAnyExpiration() called with: timestamp = $timestamp, author = $author, expireStartedAt = $expireStartedAt")
|
Log.d(TAG, "startAnyExpiration() called with: timestamp = $timestamp, author = $author, expireStartedAt = $expireStartedAt")
|
||||||
val messageRecord = mmsSmsDatabase.getMessageFor(timestamp, author) ?: return
|
val messageRecord = mmsSmsDatabase.getMessageFor(timestamp, author) ?: throw Exception("no message record!!!")
|
||||||
|
Log.d(TAG, "startAnyExpiration() $messageRecord")
|
||||||
val mms = messageRecord.isMms()
|
val mms = messageRecord.isMms()
|
||||||
getDatabase(mms).markExpireStarted(messageRecord.getId(), expireStartedAt)
|
getDatabase(mms).markExpireStarted(messageRecord.getId(), expireStartedAt)
|
||||||
scheduleDeletion(messageRecord.getId(), mms, expireStartedAt, messageRecord.expiresIn)
|
scheduleDeletion(messageRecord.getId(), mms, expireStartedAt, messageRecord.expiresIn)
|
||||||
|
@ -421,9 +421,10 @@ object MessageSender {
|
|||||||
storage.markUnidentified(timestamp, userPublicKey)
|
storage.markUnidentified(timestamp, userPublicKey)
|
||||||
// Start the disappearing messages timer if needed
|
// Start the disappearing messages timer if needed
|
||||||
Log.d("MessageSender", "Start the disappearing messages timer if needed message.recipient = ${message.recipient}, userPublicKey = $userPublicKey, isSyncMessage = $isSyncMessage")
|
Log.d("MessageSender", "Start the disappearing messages timer if needed message.recipient = ${message.recipient}, userPublicKey = $userPublicKey, isSyncMessage = $isSyncMessage")
|
||||||
message.threadID?.let(storage::getExpirationConfiguration)?.takeIf { it.expiryMode.expirySeconds > 0 }?.let { config ->
|
message.threadID?.let(storage::getExpirationConfiguration)?.expiryMode?.takeIf { it.expirySeconds > 0 }?.let { mode ->
|
||||||
if (message.recipient == userPublicKey || !isSyncMessage) {
|
if (message.recipient == userPublicKey || !isSyncMessage) {
|
||||||
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(timestamp, userPublicKey, timestamp)
|
val expireStartedAt = if (mode is ExpiryMode.AfterRead) timestamp + 1 else timestamp
|
||||||
|
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(timestamp, userPublicKey, expireStartedAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: run {
|
} ?: run {
|
||||||
|
@ -65,6 +65,8 @@ internal fun MessageReceiver.isBlocked(publicKey: String): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content, threadId: Long, openGroupID: String?) {
|
fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content, threadId: Long, openGroupID: String?) {
|
||||||
|
Log.d("MessageReceiver", "handle() called with: message = $message, proto = $proto, threadId = $threadId, openGroupID = $openGroupID")
|
||||||
|
|
||||||
// Do nothing if the message was outdated
|
// Do nothing if the message was outdated
|
||||||
if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return }
|
if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return }
|
||||||
|
|
||||||
@ -122,6 +124,7 @@ private fun MessageReceiver.handleReadReceipt(message: ReadReceipt) {
|
|||||||
private fun MessageReceiver.handleCallMessage(message: CallMessage) {
|
private fun MessageReceiver.handleCallMessage(message: CallMessage) {
|
||||||
// TODO: refactor this out to persistence, just to help debug the flow and send/receive in synchronous testing
|
// TODO: refactor this out to persistence, just to help debug the flow and send/receive in synchronous testing
|
||||||
WebRtcUtils.SIGNAL_QUEUE.trySend(message)
|
WebRtcUtils.SIGNAL_QUEUE.trySend(message)
|
||||||
|
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(message, coerceToDisappearAfterRead = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageReceiver.handleTypingIndicator(message: TypingIndicator) {
|
private fun MessageReceiver.handleTypingIndicator(message: TypingIndicator) {
|
||||||
@ -153,7 +156,7 @@ fun MessageReceiver.cancelTypingIndicatorsIfNeeded(senderPublicKey: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimerUpdate) {
|
private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimerUpdate) {
|
||||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message)
|
SSKEnvironment.shared.messageExpirationManager.insertExpirationTimerMessage(message)
|
||||||
|
|
||||||
if (isNewConfigEnabled) return
|
if (isNewConfigEnabled) return
|
||||||
|
|
||||||
@ -186,6 +189,7 @@ private fun MessageReceiver.handleDataExtractionNotification(message: DataExtrac
|
|||||||
else -> return
|
else -> return
|
||||||
}
|
}
|
||||||
storage.insertDataExtractionNotificationMessage(senderPublicKey, notification, message.sentTimestamp!!)
|
storage.insertDataExtractionNotificationMessage(senderPublicKey, notification, message.sentTimestamp!!)
|
||||||
|
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(message, coerceToDisappearAfterRead = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleConfigurationMessage(message: ConfigurationMessage) {
|
private fun handleConfigurationMessage(message: ConfigurationMessage) {
|
||||||
@ -285,6 +289,8 @@ fun MessageReceiver.handleVisibleMessage(
|
|||||||
runThreadUpdate: Boolean,
|
runThreadUpdate: Boolean,
|
||||||
runProfileUpdate: Boolean
|
runProfileUpdate: Boolean
|
||||||
): Long? {
|
): Long? {
|
||||||
|
Log.d("ReceivedMessageHandler", "handleVisibleMessage() called with: message = $message, proto = $proto, openGroupID = $openGroupID, threadId = $threadId, runThreadUpdate = $runThreadUpdate, runProfileUpdate = $runProfileUpdate")
|
||||||
|
|
||||||
val storage = MessagingModuleConfiguration.shared.storage
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
val context = MessagingModuleConfiguration.shared.context
|
val context = MessagingModuleConfiguration.shared.context
|
||||||
val userPublicKey = storage.getUserPublicKey()
|
val userPublicKey = storage.getUserPublicKey()
|
||||||
@ -386,14 +392,7 @@ fun MessageReceiver.handleVisibleMessage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Parse attachments if needed
|
// Parse attachments if needed
|
||||||
val attachments = proto.dataMessage.attachmentsList.mapNotNull { attachmentProto ->
|
val attachments = proto.dataMessage.attachmentsList.map(Attachment::fromProto).filter { it.isValid() }
|
||||||
val attachment = Attachment.fromProto(attachmentProto)
|
|
||||||
if (!attachment.isValid()) {
|
|
||||||
return@mapNotNull null
|
|
||||||
} else {
|
|
||||||
return@mapNotNull attachment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Cancel any typing indicators if needed
|
// Cancel any typing indicators if needed
|
||||||
cancelTypingIndicatorsIfNeeded(message.sender!!)
|
cancelTypingIndicatorsIfNeeded(message.sender!!)
|
||||||
// Parse reaction if needed
|
// Parse reaction if needed
|
||||||
@ -429,6 +428,7 @@ fun MessageReceiver.handleVisibleMessage(
|
|||||||
val isSms = !message.isMediaMessage() && attachments.isEmpty()
|
val isSms = !message.isMediaMessage() && attachments.isEmpty()
|
||||||
storage.setOpenGroupServerMessageID(messageID, it, threadID, isSms)
|
storage.setOpenGroupServerMessageID(messageID, it, threadID, isSms)
|
||||||
}
|
}
|
||||||
|
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(message)
|
||||||
return messageID
|
return messageID
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package org.session.libsession.utilities
|
package org.session.libsession.utilities
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||||
import org.session.libsession.messaging.contacts.Contact
|
import org.session.libsession.messaging.contacts.Contact
|
||||||
|
import org.session.libsession.messaging.messages.Message
|
||||||
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
|
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
|
||||||
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier
|
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier
|
||||||
|
import org.session.libsession.snode.SnodeAPI
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
|
|
||||||
class SSKEnvironment(
|
class SSKEnvironment(
|
||||||
@ -38,8 +41,20 @@ class SSKEnvironment(
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface MessageExpirationManagerProtocol {
|
interface MessageExpirationManagerProtocol {
|
||||||
fun setExpirationTimer(message: ExpirationTimerUpdate)
|
fun insertExpirationTimerMessage(message: ExpirationTimerUpdate)
|
||||||
fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long)
|
fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long)
|
||||||
|
fun startAnyExpiration(message: Message, coerceToDisappearAfterRead: Boolean = false) {
|
||||||
|
Log.d("MessageExpirationManagerProtocol", "startAnyExpiration() called with: message = $message, coerceToDisappearAfterRead = $coerceToDisappearAfterRead")
|
||||||
|
|
||||||
|
val timestamp = message.sentTimestamp ?: return
|
||||||
|
startAnyExpiration(
|
||||||
|
timestamp = timestamp,
|
||||||
|
author = message.sender ?: return,
|
||||||
|
expireStartedAt = if (message.expiryMode is ExpiryMode.AfterRead || coerceToDisappearAfterRead && message.expiryMode.expiryMillis > 0) SnodeAPI.nowWithOffset.coerceAtLeast(timestamp + 1)
|
||||||
|
else if (message.expiryMode is ExpiryMode.AfterSend) timestamp
|
||||||
|
else return
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
Loading…
Reference in New Issue
Block a user