mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-28 20:45:17 +00:00
Cleaned up the outdated message logic
This commit is contained in:
parent
d093d676f6
commit
6af009c9ee
@ -1221,11 +1221,6 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
|
|||||||
recipientDb.setRecipientHash(recipient, recipientHash)
|
recipientDb.setRecipientHash(recipient, recipientHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getThreadArchived(threadId: Long): Boolean {
|
|
||||||
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
|
||||||
return threadDB.getThreadArchived(threadId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getLastUpdated(threadID: Long): Long {
|
override fun getLastUpdated(threadID: Long): Long {
|
||||||
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
val threadDB = DatabaseComponent.get(context).threadDatabase()
|
||||||
return threadDB.getLastUpdated(threadID)
|
return threadDB.getLastUpdated(threadID)
|
||||||
|
@ -658,24 +658,6 @@ public class ThreadDatabase extends Database {
|
|||||||
return getOrCreateThreadIdFor(recipient, DistributionTypes.DEFAULT);
|
return getOrCreateThreadIdFor(recipient, DistributionTypes.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getThreadArchived(long threadId) {
|
|
||||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
|
||||||
Cursor cursor = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
cursor = db.query(TABLE_NAME, null, ID + " = ?", new String[] {threadId+""}, null, null, null);
|
|
||||||
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
return (cursor.getInt(cursor.getColumnIndexOrThrow(ARCHIVED)) == 1);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThreadArchived(long threadId) {
|
public void setThreadArchived(long threadId) {
|
||||||
ContentValues contentValues = new ContentValues(1);
|
ContentValues contentValues = new ContentValues(1);
|
||||||
contentValues.put(ARCHIVED, 1);
|
contentValues.put(ARCHIVED, 1);
|
||||||
|
@ -166,7 +166,6 @@ interface StorageProtocol {
|
|||||||
fun getThreadId(address: Address): Long?
|
fun getThreadId(address: Address): Long?
|
||||||
fun getThreadId(recipient: Recipient): Long?
|
fun getThreadId(recipient: Recipient): Long?
|
||||||
fun getThreadIdForMms(mmsId: Long): Long
|
fun getThreadIdForMms(mmsId: Long): Long
|
||||||
fun getThreadArchived(threadId: Long): Boolean
|
|
||||||
fun getLastUpdated(threadID: Long): Long
|
fun getLastUpdated(threadID: Long): Long
|
||||||
fun trimThread(threadID: Long, threadLimit: Int)
|
fun trimThread(threadID: Long, threadLimit: Int)
|
||||||
fun trimThreadBefore(threadID: Long, timestamp: Long)
|
fun trimThreadBefore(threadID: Long, timestamp: Long)
|
||||||
|
@ -61,57 +61,61 @@ 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?) {
|
||||||
|
// Do nothing if the message was outdated
|
||||||
|
if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return }
|
||||||
|
|
||||||
when (message) {
|
when (message) {
|
||||||
is ReadReceipt -> handleReadReceipt(message)
|
is ReadReceipt -> handleReadReceipt(message)
|
||||||
is TypingIndicator -> handleTypingIndicator(message)
|
is TypingIndicator -> handleTypingIndicator(message)
|
||||||
is ClosedGroupControlMessage -> handleClosedGroupControlMessage(message)
|
is ClosedGroupControlMessage -> handleClosedGroupControlMessage(message)
|
||||||
is ExpirationTimerUpdate -> handleExpirationTimerUpdate(message)
|
is ExpirationTimerUpdate -> handleExpirationTimerUpdate(message)
|
||||||
is DataExtractionNotification -> handleDataExtractionNotification(message, threadId)
|
is DataExtractionNotification -> handleDataExtractionNotification(message)
|
||||||
is ConfigurationMessage -> handleConfigurationMessage(message)
|
is ConfigurationMessage -> handleConfigurationMessage(message)
|
||||||
is UnsendRequest -> handleUnsendRequest(message)
|
is UnsendRequest -> handleUnsendRequest(message)
|
||||||
is MessageRequestResponse -> handleMessageRequestResponse(message, threadId)
|
is MessageRequestResponse -> handleMessageRequestResponse(message)
|
||||||
is VisibleMessage -> handleVisibleMessage(
|
is VisibleMessage -> handleVisibleMessage(
|
||||||
message, proto, openGroupID, threadId,
|
message, proto, openGroupID, threadId,
|
||||||
runThreadUpdate = true,
|
runThreadUpdate = true,
|
||||||
runProfileUpdate = true
|
runProfileUpdate = true
|
||||||
)
|
)
|
||||||
is CallMessage -> handleCallMessage(message, threadId)
|
is CallMessage -> handleCallMessage(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MessageReceiver.messageIsOutdated(message: Message, threadId: Long, openGroupID: String?): Boolean {
|
||||||
|
when (message) {
|
||||||
|
is ReadReceipt -> return false // No visible artifact created so better to keep for more reliable read states
|
||||||
|
is UnsendRequest -> return false // We should always process the removal of messages just in case
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the state of the conversation and the validity of the message
|
||||||
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
|
val userPublicKey = storage.getUserPublicKey()!!
|
||||||
|
val threadRecipient = storage.getRecipientForThread(threadId)
|
||||||
|
val conversationVisibleInConfig = storage.conversationInConfig(
|
||||||
|
if (message.groupPublicKey == null) threadRecipient?.address?.serialize() else null,
|
||||||
|
message.groupPublicKey,
|
||||||
|
openGroupID,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
val canPerformChange = storage.canPerformConfigChange(
|
||||||
|
if (threadRecipient?.address?.serialize() == userPublicKey) SharedConfigMessage.Kind.USER_PROFILE.name else SharedConfigMessage.Kind.CONTACTS.name,
|
||||||
|
userPublicKey,
|
||||||
|
message.sentTimestamp!!
|
||||||
|
)
|
||||||
|
|
||||||
|
// If the thread is visible or the message was sent more recently than the last config message (minus
|
||||||
|
// buffer period) then we should process the message, if not then throw as the message is outdated
|
||||||
|
return (conversationVisibleInConfig || canPerformChange)
|
||||||
|
}
|
||||||
|
|
||||||
// region Control Messages
|
// region Control Messages
|
||||||
private fun MessageReceiver.handleReadReceipt(message: ReadReceipt) {
|
private fun MessageReceiver.handleReadReceipt(message: ReadReceipt) {
|
||||||
val context = MessagingModuleConfiguration.shared.context
|
val context = MessagingModuleConfiguration.shared.context
|
||||||
SSKEnvironment.shared.readReceiptManager.processReadReceipts(context, message.sender!!, message.timestamps!!, message.receivedTimestamp!!)
|
SSKEnvironment.shared.readReceiptManager.processReadReceipts(context, message.sender!!, message.timestamps!!, message.receivedTimestamp!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageReceiver.handleCallMessage(message: CallMessage, threadId: Long) {
|
private fun MessageReceiver.handleCallMessage(message: CallMessage) {
|
||||||
// Only process the message if the thread is not archived or it was sent after the libSession buffer period
|
|
||||||
val storage = MessagingModuleConfiguration.shared.storage
|
|
||||||
val userPublicKey = storage.getUserPublicKey()!!
|
|
||||||
val recipient = storage.getRecipientForThread(threadId)
|
|
||||||
val dbThreadIsVisible = (
|
|
||||||
threadId > 0 &&
|
|
||||||
recipient != null &&
|
|
||||||
!recipient.isContactRecipient &&
|
|
||||||
!storage.getThreadArchived(threadId)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
|
||||||
!dbThreadIsVisible &&
|
|
||||||
!storage.conversationInConfig(
|
|
||||||
recipient?.address?.serialize(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
true
|
|
||||||
) &&
|
|
||||||
!storage.canPerformConfigChange(
|
|
||||||
SharedConfigMessage.Kind.CONTACTS.name,
|
|
||||||
userPublicKey,
|
|
||||||
message.sentTimestamp!!
|
|
||||||
)
|
|
||||||
) { return }
|
|
||||||
|
|
||||||
// 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)
|
||||||
}
|
}
|
||||||
@ -152,37 +156,12 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification, threadId: Long) {
|
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {
|
||||||
// We don't handle data extraction messages for groups (they shouldn't be sent, but just in case we filter them here too)
|
// We don't handle data extraction messages for groups (they shouldn't be sent, but just in case we filter them here too)
|
||||||
if (message.groupPublicKey != null) return
|
if (message.groupPublicKey != null) return
|
||||||
val storage = MessagingModuleConfiguration.shared.storage
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
val senderPublicKey = message.sender!!
|
val senderPublicKey = message.sender!!
|
||||||
|
|
||||||
// Only process the message if the thread is not archived or it was sent after the libSession buffer period
|
|
||||||
val userPublicKey = storage.getUserPublicKey()!!
|
|
||||||
val recipient = storage.getRecipientForThread(threadId)
|
|
||||||
val dbThreadIsVisible = (
|
|
||||||
threadId > 0 &&
|
|
||||||
recipient != null &&
|
|
||||||
!recipient.isContactRecipient &&
|
|
||||||
!storage.getThreadArchived(threadId)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
|
||||||
!dbThreadIsVisible &&
|
|
||||||
!storage.conversationInConfig(
|
|
||||||
recipient?.address?.serialize(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
true
|
|
||||||
) &&
|
|
||||||
!storage.canPerformConfigChange(
|
|
||||||
if (recipient?.address?.serialize() == userPublicKey) SharedConfigMessage.Kind.USER_PROFILE.name else SharedConfigMessage.Kind.CONTACTS.name,
|
|
||||||
userPublicKey,
|
|
||||||
message.sentTimestamp!!
|
|
||||||
)
|
|
||||||
) { return }
|
|
||||||
|
|
||||||
val notification: DataExtractionNotificationInfoMessage = when(message.kind) {
|
val notification: DataExtractionNotificationInfoMessage = when(message.kind) {
|
||||||
is DataExtractionNotification.Kind.Screenshot -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.SCREENSHOT)
|
is DataExtractionNotification.Kind.Screenshot -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.SCREENSHOT)
|
||||||
is DataExtractionNotification.Kind.MediaSaved -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED)
|
is DataExtractionNotification.Kind.MediaSaved -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED)
|
||||||
@ -267,33 +246,7 @@ fun MessageReceiver.handleUnsendRequest(message: UnsendRequest): Long? {
|
|||||||
return deletedMessageId
|
return deletedMessageId
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleMessageRequestResponse(message: MessageRequestResponse, threadId: Long) {
|
fun handleMessageRequestResponse(message: MessageRequestResponse) {
|
||||||
// Only process the message if the thread is not archived or it was sent after the libSession buffer period
|
|
||||||
val storage = MessagingModuleConfiguration.shared.storage
|
|
||||||
val userPublicKey = storage.getUserPublicKey()!!
|
|
||||||
val recipient = storage.getRecipientForThread(threadId)
|
|
||||||
val dbThreadIsVisible = (
|
|
||||||
threadId > 0 &&
|
|
||||||
recipient != null &&
|
|
||||||
!recipient.isContactRecipient &&
|
|
||||||
!storage.getThreadArchived(threadId)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
|
||||||
!dbThreadIsVisible &&
|
|
||||||
!storage.conversationInConfig(
|
|
||||||
recipient?.address?.serialize(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
true
|
|
||||||
) &&
|
|
||||||
!storage.canPerformConfigChange(
|
|
||||||
SharedConfigMessage.Kind.CONTACTS.name,
|
|
||||||
userPublicKey,
|
|
||||||
message.sentTimestamp!!
|
|
||||||
)
|
|
||||||
) { return }
|
|
||||||
|
|
||||||
MessagingModuleConfiguration.shared.storage.insertMessageRequestResponse(message)
|
MessagingModuleConfiguration.shared.storage.insertMessageRequestResponse(message)
|
||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
@ -308,32 +261,11 @@ fun MessageReceiver.handleVisibleMessage(
|
|||||||
): Long? {
|
): Long? {
|
||||||
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()
|
||||||
val messageSender: String? = message.sender
|
val messageSender: String? = message.sender
|
||||||
|
|
||||||
// Only process the message if the thread is not archived or it was sent after the libSession buffer period
|
// Do nothing if the message was outdated
|
||||||
val threadRecipient = storage.getRecipientForThread(threadId)
|
if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return null }
|
||||||
val dbThreadIsVisible = (
|
|
||||||
threadId > 0 &&
|
|
||||||
threadRecipient != null &&
|
|
||||||
!threadRecipient.isContactRecipient &&
|
|
||||||
!storage.getThreadArchived(threadId)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
|
||||||
!dbThreadIsVisible &&
|
|
||||||
!storage.conversationInConfig(
|
|
||||||
if (message.groupPublicKey == null) threadRecipient?.address?.serialize() else null,
|
|
||||||
message.groupPublicKey,
|
|
||||||
openGroupID,
|
|
||||||
true
|
|
||||||
) &&
|
|
||||||
!storage.canPerformConfigChange(
|
|
||||||
if (threadRecipient?.address?.serialize() == userPublicKey) SharedConfigMessage.Kind.USER_PROFILE.name else SharedConfigMessage.Kind.CONTACTS.name,
|
|
||||||
userPublicKey,
|
|
||||||
message.sentTimestamp!!
|
|
||||||
)
|
|
||||||
) { return null }
|
|
||||||
|
|
||||||
// Get or create thread
|
// Get or create thread
|
||||||
// FIXME: In case this is an open group this actually * doesn't * create the thread if it doesn't yet
|
// FIXME: In case this is an open group this actually * doesn't * create the thread if it doesn't yet
|
||||||
@ -341,6 +273,7 @@ fun MessageReceiver.handleVisibleMessage(
|
|||||||
val threadID = storage.getThreadIdFor(message.syncTarget ?: messageSender!!, message.groupPublicKey, openGroupID, createThread = true)
|
val threadID = storage.getThreadIdFor(message.syncTarget ?: messageSender!!, message.groupPublicKey, openGroupID, createThread = true)
|
||||||
// Thread doesn't exist; should only be reached in a case where we are processing open group messages for a no longer existent thread
|
// Thread doesn't exist; should only be reached in a case where we are processing open group messages for a no longer existent thread
|
||||||
?: throw MessageReceiver.Error.NoThread
|
?: throw MessageReceiver.Error.NoThread
|
||||||
|
val threadRecipient = storage.getRecipientForThread(threadID)
|
||||||
val userBlindedKey = openGroupID?.let {
|
val userBlindedKey = openGroupID?.let {
|
||||||
val openGroup = storage.getOpenGroup(threadID) ?: return@let null
|
val openGroup = storage.getOpenGroup(threadID) ?: return@let null
|
||||||
val blindedKey = SodiumUtilities.blindedKeyPair(openGroup.publicKey, MessagingModuleConfiguration.shared.getUserED25519KeyPair()!!) ?: return@let null
|
val blindedKey = SodiumUtilities.blindedKeyPair(openGroup.publicKey, MessagingModuleConfiguration.shared.getUserED25519KeyPair()!!) ?: return@let null
|
||||||
|
Loading…
Reference in New Issue
Block a user