Fix Message#expiryMode de/serialisation

This commit is contained in:
Andrew
2024-01-30 15:53:24 +10:30
parent cb0327ecb2
commit 4c7485f53d
26 changed files with 236 additions and 217 deletions

View File

@@ -14,6 +14,7 @@ import org.session.libsession.utilities.ExpirationUtil
import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.getExpirationTypeDisplayValue
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.showSessionDialog
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
@@ -25,11 +26,11 @@ class DisappearingMessages @Inject constructor(
private val textSecurePreferences: TextSecurePreferences,
private val messageExpirationManager: MessageExpirationManagerProtocol,
) {
fun set(threadId: Long, address: Address, mode: ExpiryMode) {
fun set(threadId: Long, address: Address, mode: ExpiryMode, isGroup: Boolean) {
val expiryChangeTimestampMs = SnodeAPI.nowWithOffset
MessagingModuleConfiguration.shared.storage.setExpirationConfiguration(ExpirationConfiguration(threadId, mode, expiryChangeTimestampMs))
val message = ExpirationTimerUpdate().apply {
val message = ExpirationTimerUpdate(isGroup = isGroup).apply {
expiryMode = mode
sender = textSecurePreferences.getLocalNumber()
isSenderSelf = true
@@ -62,7 +63,7 @@ class DisappearingMessages @Inject constructor(
text = if (message.expiresIn == 0L) R.string.dialog_disappearing_messages_follow_setting_confirm else R.string.dialog_disappearing_messages_follow_setting_set,
contentDescription = if (message.expiresIn == 0L) R.string.AccessibilityId_confirm else R.string.AccessibilityId_set_button
) {
set(message.threadId, message.recipient.address, message.expiryMode)
set(message.threadId, message.recipient.address, message.expiryMode, message.recipient.isClosedGroupRecipient)
}
cancelButton()
}

View File

@@ -87,7 +87,7 @@ class DisappearingMessagesViewModel(
return@launch
}
disappearingMessages.set(threadId, address, mode)
disappearingMessages.set(threadId, address, mode, state.isGroup)
_event.send(Event.SUCCESS)
}

View File

@@ -72,6 +72,7 @@ import org.session.libsession.messaging.jobs.JobQueue
import org.session.libsession.messaging.mentions.Mention
import org.session.libsession.messaging.mentions.MentionsManager
import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.messages.applyExpiryMode
import org.session.libsession.messaging.messages.control.DataExtractionNotification
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage
@@ -1574,7 +1575,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
return null
}
// Create the message
val message = VisibleMessage()
val message = VisibleMessage().applyExpiryMode(viewModel.threadId)
message.sentTimestamp = sentTimestamp
message.text = text
val expiresInMillis = viewModel.expirationConfiguration?.expiryMode?.expiryMillis ?: 0
@@ -1609,7 +1610,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
val sentTimestamp = SnodeAPI.nowWithOffset
processMessageRequestApproval()
// Create the message
val message = VisibleMessage()
val message = VisibleMessage().applyExpiryMode()
message.sentTimestamp = sentTimestamp
message.text = body
val quote = quotedMessage?.let {

View File

@@ -30,6 +30,10 @@ class ExpirationTimerView @JvmOverloads constructor(
R.drawable.timer60
)
fun setTimerIcon() {
setExpirationTime(0L, 0L)
}
fun setExpirationTime(startedAt: Long, expiresIn: Long) {
if (expiresIn == 0L) {
setImageResource(R.drawable.timer55)

View File

@@ -53,12 +53,19 @@ class ControlMessageView : LinearLayout {
Log.d(TAG, "bind() called, messageBody = $messageBody")
expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn)
val threadRecipient = DatabaseComponent.get(context).threadDatabase().getRecipientForThreadId(message.threadId)
if (threadRecipient?.isClosedGroupRecipient == true) {
expirationTimerView.setTimerIcon()
} else {
expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn)
}
followSetting.isVisible = ExpirationConfiguration.isNewConfigEnabled
&& !message.isOutgoing
&& message.expiryMode != (MessagingModuleConfiguration.shared.storage.getExpirationConfiguration(message.threadId)?.expiryMode ?: ExpiryMode.NONE)
&& DatabaseComponent.get(context).threadDatabase().getRecipientForThreadId(message.threadId)?.isGroupRecipient != true
&& threadRecipient?.isGroupRecipient != true
followSetting.setOnClickListener { disappearingMessages.showFollowSettingDialog(context, message) }
}

View File

@@ -4,11 +4,11 @@ import org.thoughtcrime.securesms.conversation.disappearingmessages.ExpiryType
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId
data class MarkedMessageInfo(val syncMessageId: SyncMessageId, val expirationInfo: ExpirationInfo) {
fun guessExpiryType(): ExpiryType = expirationInfo.run {
when {
syncMessageId.timetamp == expireStarted -> ExpiryType.AFTER_SEND
expiresIn > 0 -> ExpiryType.AFTER_READ
else -> ExpiryType.NONE
}
val expiryType get() = when {
syncMessageId.timetamp == expirationInfo.expireStarted -> ExpiryType.AFTER_SEND
expirationInfo.expiresIn > 0 -> ExpiryType.AFTER_READ
else -> ExpiryType.NONE
}
val expiryMode get() = expiryType.mode(expirationInfo.expiresIn)
}

View File

@@ -382,9 +382,6 @@ open class Storage(
DatabaseComponent.get(context).lokiMessageDatabase().setMessageServerHash(id, message.isMediaMessage(), serverHash)
}
}
if (expiryMode is ExpiryMode.AfterSend) {
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(message.sentTimestamp!!, message.sender!!, expireStartedAt)
}
return messageID
}
@@ -972,26 +969,24 @@ open class Storage(
val recipient = Recipient.from(context, fromSerialized(groupID), false)
val threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient)
val expirationConfig = getExpirationConfiguration(threadId)
val expiryMode = expirationConfig?.expiryMode
val expiresInMillis = expiryMode?.expiryMillis ?: 0
val expiryMode = expirationConfig?.expiryMode ?: ExpiryMode.NONE
val expiresInMillis = expiryMode.expiryMillis
val expireStartedAt = if (expiryMode is ExpiryMode.AfterSend) sentTimestamp else 0
val m = IncomingTextMessage(fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), expiresInMillis, expireStartedAt, true, false)
val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON()
val infoMessage = IncomingGroupMessage(m, groupID, updateData, true)
val smsDB = DatabaseComponent.get(context).smsDatabase()
smsDB.insertMessageInbox(infoMessage, true)
if (expiryMode is ExpiryMode.AfterSend) {
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(sentTimestamp, senderPublicKey, expireStartedAt)
}
SSKEnvironment.shared.messageExpirationManager.maybeStartExpiration(sentTimestamp, senderPublicKey, expiryMode)
}
override fun insertOutgoingInfoMessage(context: Context, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection<String>, admins: Collection<String>, threadID: Long, sentTimestamp: Long) {
val userPublicKey = getUserPublicKey()
val userPublicKey = getUserPublicKey()!!
val recipient = Recipient.from(context, fromSerialized(groupID), false)
val threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient)
val expirationConfig = getExpirationConfiguration(threadId)
val expiryMode = expirationConfig?.expiryMode
val expiresInMillis = expiryMode?.expiryMillis ?: 0
val expiryMode = expirationConfig?.expiryMode ?: ExpiryMode.NONE
val expiresInMillis = expiryMode.expiryMillis
val expireStartedAt = if (expiryMode is ExpiryMode.AfterSend) sentTimestamp else 0
val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() ?: ""
val infoMessage = OutgoingGroupMediaMessage(recipient, updateData, groupID, null, sentTimestamp, expiresInMillis, expireStartedAt, true, null, listOf(), listOf())
@@ -1000,9 +995,7 @@ open class Storage(
if (mmsSmsDB.getMessageFor(sentTimestamp, userPublicKey) != null) return
val infoMessageID = mmsDB.insertMessageOutbox(infoMessage, threadID, false, null, runThreadUpdate = true)
mmsDB.markAsSent(infoMessageID, true)
if (expiryMode is ExpiryMode.AfterSend) {
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(sentTimestamp, userPublicKey!!, expireStartedAt)
}
SSKEnvironment.shared.messageExpirationManager.maybeStartExpiration(sentTimestamp, userPublicKey, expiryMode)
}
override fun isClosedGroup(publicKey: String): Boolean {
@@ -1403,8 +1396,8 @@ open class Storage(
if (recipient.isBlocked) return
val threadId = getThreadId(recipient) ?: return
val expirationConfig = getExpirationConfiguration(threadId)
val expiryMode = expirationConfig?.expiryMode
val expiresInMillis = expiryMode?.expiryMillis ?: 0
val expiryMode = expirationConfig?.expiryMode ?: ExpiryMode.NONE
val expiresInMillis = expiryMode.expiryMillis
val expireStartedAt = if (expiryMode is ExpiryMode.AfterSend) sentTimestamp else 0
val mediaMessage = IncomingMediaMessage(
address,
@@ -1426,9 +1419,8 @@ open class Storage(
)
database.insertSecureDecryptedMessageInbox(mediaMessage, threadId, runThreadUpdate = true)
if (expiryMode is ExpiryMode.AfterSend) {
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(sentTimestamp, senderPublicKey, expireStartedAt)
}
SSKEnvironment.shared.messageExpirationManager.maybeStartExpiration(sentTimestamp, senderPublicKey, expiryMode)
}
override fun insertMessageRequestResponse(response: MessageRequestResponse) {
@@ -1557,14 +1549,12 @@ open class Storage(
val recipient = Recipient.from(context, address, false)
val threadId = DatabaseComponent.get(context).threadDatabase().getOrCreateThreadIdFor(recipient)
val expirationConfig = getExpirationConfiguration(threadId)
val expiryMode = expirationConfig?.expiryMode
val expiresInMillis = expiryMode?.expiryMillis ?: 0
val expiryMode = expirationConfig?.expiryMode?.coerceSendToRead() ?: ExpiryMode.NONE
val expiresInMillis = expiryMode.expiryMillis
val expireStartedAt = if (expiryMode is ExpiryMode.AfterSend) sentTimestamp else 0
val callMessage = IncomingTextMessage.fromCallInfo(callMessageType, address, Optional.absent(), sentTimestamp, expiresInMillis, expireStartedAt)
database.insertCallMessage(callMessage)
if (expiryMode is ExpiryMode.AfterSend) {
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(sentTimestamp, senderPublicKey, expireStartedAt)
}
SSKEnvironment.shared.messageExpirationManager.maybeStartExpiration(sentTimestamp, senderPublicKey, expiryMode)
}
override fun conversationHasOutgoing(userPublicKey: String): Boolean {

View File

@@ -11,6 +11,7 @@ import org.session.libsession.messaging.messages.control.ReadReceipt
import org.session.libsession.messaging.sending_receiving.MessageSender.send
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.SnodeAPI.nowWithOffset
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled
import org.session.libsession.utilities.associateByNotNull
@@ -62,6 +63,18 @@ class MarkReadReceiver : BroadcastReceiver() {
sendReadReceipts(context, markedReadMessages)
markedReadMessages
.filter { it.expiryType == ExpiryType.AFTER_READ }
.forEach { info ->
DatabaseComponent.get(context).mmsSmsDatabase().getMessageForTimestamp(info.syncMessageId.timetamp)
?.takeUnless { it.isExpirationTimerUpdate && it.recipient.isClosedGroupRecipient }
?.run {
SSKEnvironment.shared.messageExpirationManager.startDisappearAfterRead(
info.syncMessageId.timetamp,
info.syncMessageId.address.serialize()
)
}
}
markedReadMessages.forEach { scheduleDeletion(context, it.expirationInfo) }
hashToDisappearAfterReadMessage(context, markedReadMessages)?.let {
@@ -77,7 +90,7 @@ class MarkReadReceiver : BroadcastReceiver() {
val loki = DatabaseComponent.get(context).lokiMessageDatabase()
return markedReadMessages
.filter { it.guessExpiryType() == ExpiryType.AFTER_READ }
.filter { it.expiryType == ExpiryType.AFTER_READ }
.associateByNotNull { it.expirationInfo.run { loki.getMessageServerHash(id, isMms) } }
.takeIf { it.isNotEmpty() }
}

View File

@@ -49,6 +49,9 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco
fun scheduleDeletion(id: Long, mms: Boolean, startedAtTimestamp: Long, expiresInMillis: Long) {
Log.d(TAG, "scheduleDeletion() called with: id = $id, mms = $mms, startedAtTimestamp = $startedAtTimestamp, expiresInMillis = $expiresInMillis")
if (startedAtTimestamp <= 0) return
val expiresAtMillis = startedAtTimestamp + expiresInMillis
synchronized(expiringMessageReferences) {
expiringMessageReferences += ExpiringMessageReference(id, mms, expiresAtMillis)
@@ -164,16 +167,16 @@ class ExpiringMessageManager(context: Context) : MessageExpirationManagerProtoco
insertIncomingExpirationTimerMessage(message, expireStartedAt)
}
startAnyExpiration(message)
maybeStartExpiration(message)
}
override fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long) {
Log.d(TAG, "startAnyExpiration() called with: timestamp = $timestamp, author = $author, expireStartedAt = $expireStartedAt")
val messageRecord = mmsSmsDatabase.getMessageFor(timestamp, author) ?: throw Exception("no message record!!!")
Log.d(TAG, "startAnyExpiration() $messageRecord")
val mms = messageRecord.isMms()
getDatabase(mms).markExpireStarted(messageRecord.getId(), expireStartedAt)
scheduleDeletion(messageRecord.getId(), mms, expireStartedAt, messageRecord.expiresIn)
mmsSmsDatabase.getMessageFor(timestamp, author)?.run {
getDatabase(isMms()).markExpireStarted(getId(), expireStartedAt)
scheduleDeletion(getId(), isMms(), expireStartedAt, expiresIn)
} ?: Log.e(TAG, "no message record!!!")
}
private inner class LoadTask : Runnable {

View File

@@ -16,6 +16,7 @@ import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.functional.bind
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.calls.CallMessageType
import org.session.libsession.messaging.messages.applyExpiryMode
import org.session.libsession.messaging.messages.control.CallMessage
import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.snode.SnodeAPI
@@ -57,8 +58,12 @@ import java.util.ArrayDeque
import java.util.UUID
import org.thoughtcrime.securesms.webrtc.data.State as CallState
class CallManager(context: Context, audioManager: AudioManagerCompat, private val storage: StorageProtocol): PeerConnection.Observer,
SignalAudioManager.EventListener, CameraEventListener, DataChannel.Observer {
class CallManager(
private val context: Context,
audioManager: AudioManagerCompat,
private val storage: StorageProtocol
): PeerConnection.Observer,
SignalAudioManager.EventListener, CameraEventListener, DataChannel.Observer {
sealed class StateEvent {
data class AudioEnabled(val isEnabled: Boolean): StateEvent()
@@ -293,17 +298,16 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
while (pendingOutgoingIceUpdates.isNotEmpty()) {
currentPendings.add(pendingOutgoingIceUpdates.pop())
}
val sdps = currentPendings.map { it.sdp }
val sdpMLineIndexes = currentPendings.map { it.sdpMLineIndex }
val sdpMids = currentPendings.map { it.sdpMid }
MessageSender.sendNonDurably(CallMessage(
ICE_CANDIDATES,
sdps = sdps,
sdpMLineIndexes = sdpMLineIndexes,
sdpMids = sdpMids,
currentCallId
), currentRecipient.address, isSyncMessage = currentRecipient.isLocalNumber)
CallMessage(
ICE_CANDIDATES,
sdps = currentPendings.map(IceCandidate::sdp),
sdpMLineIndexes = currentPendings.map(IceCandidate::sdpMLineIndex),
sdpMids = currentPendings.map(IceCandidate::sdpMid),
currentCallId
)
.applyExpiryMode()
.also { MessageSender.sendNonDurably(it, currentRecipient.address, isSyncMessage = currentRecipient.isLocalNumber) }
}
}
}