mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-11 20:27:47 +00:00
fix: compile issues and dependencies resolved to use shared configs throughout apps
This commit is contained in:
@@ -152,7 +152,11 @@ class BatchMessageReceiveJob(
|
||||
try {
|
||||
when (message) {
|
||||
is VisibleMessage -> {
|
||||
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID, newLastSeen)
|
||||
MessageReceiver.updateExpiryIfNeeded(
|
||||
message,
|
||||
proto,
|
||||
openGroupID
|
||||
)
|
||||
val isUserBlindedSender =
|
||||
message.sender == serverPublicKey?.let {
|
||||
SodiumUtilities.blindedKeyPair(
|
||||
|
@@ -4,10 +4,10 @@ import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
|
||||
data class ExpirationConfiguration(
|
||||
val threadId: Long = -1,
|
||||
val expirationType: ExpiryMode? = null,
|
||||
val expiryMode: ExpiryMode? = null,
|
||||
val updatedTimestampMs: Long = 0
|
||||
) {
|
||||
val isEnabled = expirationType != null && expirationType.expirySeconds > 0
|
||||
val isEnabled = expiryMode != null && expiryMode.expirySeconds > 0
|
||||
|
||||
companion object {
|
||||
val isNewConfigEnabled = false /* TODO: System.currentTimeMillis() > 1_676_851_200_000 // 13/02/2023 */
|
||||
|
@@ -1,12 +1,14 @@
|
||||
package org.session.libsession.messaging.messages
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.session.libsession.database.StorageProtocol
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
|
||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||
import org.session.libsession.utilities.GroupUtil
|
||||
import org.session.libsignal.protos.SignalServiceProtos
|
||||
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
|
||||
|
||||
abstract class Message {
|
||||
var id: Long? = null
|
||||
@@ -60,10 +62,16 @@ abstract class Message {
|
||||
expirationTimer = 0
|
||||
return this
|
||||
}
|
||||
if (config.isEnabled) {
|
||||
expirationTimer = config.durationSeconds
|
||||
if (config.isEnabled && config.expiryMode != null) {
|
||||
expirationTimer = config.expiryMode.expirySeconds.toInt()
|
||||
lastDisappearingMessageChangeTimestamp = config.updatedTimestampMs
|
||||
expirationType = config.expirationType
|
||||
config.expiryMode.let { expiryMode ->
|
||||
when (expiryMode) {
|
||||
is ExpiryMode.AfterSend -> expirationType = ExpirationType.DELETE_AFTER_SEND
|
||||
is ExpiryMode.AfterRead -> expirationType = ExpirationType.DELETE_AFTER_READ
|
||||
ExpiryMode.NONE -> { /* do nothing */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
@@ -4,16 +4,15 @@ import com.google.protobuf.ByteString
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.utilities.Address
|
||||
import org.session.libsession.utilities.GroupUtil
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.ProfileKeyUtil
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
|
||||
import org.session.libsignal.crypto.ecc.DjbECPublicKey
|
||||
import org.session.libsignal.crypto.ecc.ECKeyPair
|
||||
import org.session.libsignal.protos.SignalServiceProtos
|
||||
import org.session.libsignal.utilities.Hex
|
||||
import org.session.libsignal.utilities.removingIdPrefixIfNeeded
|
||||
import org.session.libsignal.utilities.toHexString
|
||||
import org.session.libsignal.utilities.Hex
|
||||
|
||||
class ConfigurationMessage(var closedGroups: List<ClosedGroup>, var openGroups: List<String>, var contacts: List<Contact>,
|
||||
var displayName: String, var profilePicture: String?, var profileKey: ByteArray) : ControlMessage() {
|
||||
@@ -130,7 +129,14 @@ class ConfigurationMessage(var closedGroups: List<ClosedGroup>, var openGroups:
|
||||
val encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey) ?: continue
|
||||
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(group.encodedId))
|
||||
val expiryConfig = storage.getExpirationConfiguration(threadID)
|
||||
val closedGroup = ClosedGroup(groupPublicKey, group.title, encryptionKeyPair, group.members.map { it.serialize() }, group.admins.map { it.serialize() }, expiryConfig?.durationSeconds ?: 0)
|
||||
val closedGroup = ClosedGroup(
|
||||
groupPublicKey,
|
||||
group.title,
|
||||
encryptionKeyPair,
|
||||
group.members.map { it.serialize() },
|
||||
group.admins.map { it.serialize() },
|
||||
expiryConfig?.expiryMode?.expirySeconds?.toInt() ?: 0
|
||||
)
|
||||
closedGroups.add(closedGroup)
|
||||
}
|
||||
if (group.isOpenGroup) {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package org.session.libsession.messaging.sending_receiving
|
||||
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import nl.komponents.kovenant.Promise
|
||||
import nl.komponents.kovenant.deferred
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
@@ -33,7 +34,6 @@ import org.session.libsession.utilities.GroupUtil
|
||||
import org.session.libsession.utilities.SSKEnvironment
|
||||
import org.session.libsignal.crypto.PushTransportDetails
|
||||
import org.session.libsignal.protos.SignalServiceProtos
|
||||
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
|
||||
import org.session.libsignal.utilities.Base64
|
||||
import org.session.libsignal.utilities.IdPrefix
|
||||
import org.session.libsignal.utilities.Namespace
|
||||
@@ -256,8 +256,9 @@ object MessageSender {
|
||||
storage.getOrCreateThreadIdFor(Address.fromSerialized(address!!))
|
||||
}
|
||||
val config = storage.getExpirationConfiguration(threadId) ?: return null
|
||||
return if (config.isEnabled && (config.expirationType == ExpirationType.DELETE_AFTER_SEND || isSyncMessage)) {
|
||||
config.durationSeconds * 1000L
|
||||
val expiryMode = config.expiryMode
|
||||
return if (config.isEnabled && (expiryMode is ExpiryMode.AfterSend || isSyncMessage)) {
|
||||
(expiryMode?.expirySeconds ?: 0L) * 1000L
|
||||
} else null
|
||||
}
|
||||
|
||||
|
@@ -131,7 +131,7 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
|
||||
throw Error.NoThread
|
||||
}
|
||||
val threadId = storage.getOrCreateThreadIdFor(fromSerialized(groupID))
|
||||
val expireTimer = storage.getExpirationConfiguration(threadId)?.durationSeconds ?: 0
|
||||
val expireTimer = storage.getExpirationConfiguration(threadId)?.expiryMode?.expirySeconds ?: 0
|
||||
if (membersToAdd.isEmpty()) {
|
||||
Log.d("Loki", "Invalid closed group update.")
|
||||
throw Error.InvalidClosedGroupUpdate
|
||||
@@ -156,7 +156,14 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
|
||||
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
||||
// Send closed group update messages to any new members individually
|
||||
for (member in membersToAdd) {
|
||||
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, expireTimer)
|
||||
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(
|
||||
ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)),
|
||||
name,
|
||||
encryptionKeyPair,
|
||||
membersAsData,
|
||||
adminsAsData,
|
||||
expireTimer.toInt()
|
||||
)
|
||||
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind, groupID)
|
||||
// It's important that the sent timestamp of this message is greater than the sent timestamp
|
||||
// of the `MembersAdded` message above. The reason is that upon receiving this `New` message,
|
||||
|
@@ -2,6 +2,7 @@ package org.session.libsession.messaging.sending_receiving
|
||||
|
||||
import android.text.TextUtils
|
||||
import network.loki.messenger.libsession_util.ConfigBase
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.session.libsession.avatars.AvatarHelper
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.messaging.jobs.BackgroundGroupAddJob
|
||||
@@ -39,6 +40,7 @@ import org.session.libsession.utilities.GroupUtil.doubleEncodeGroupID
|
||||
import org.session.libsession.utilities.ProfileKeyUtil
|
||||
import org.session.libsession.utilities.SSKEnvironment
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.expiryMode
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
|
||||
import org.session.libsignal.crypto.ecc.DjbECPublicKey
|
||||
@@ -67,7 +69,7 @@ fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content,
|
||||
// Do nothing if the message was outdated
|
||||
if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return }
|
||||
|
||||
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID)
|
||||
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID, )
|
||||
when (message) {
|
||||
is ReadReceipt -> handleReadReceipt(message)
|
||||
is TypingIndicator -> handleTypingIndicator(message)
|
||||
@@ -157,8 +159,8 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
|
||||
val module = MessagingModuleConfiguration.shared
|
||||
val recipient = Recipient.from(module.context, Address.fromSerialized(message.sender!!), false)
|
||||
val type = when {
|
||||
recipient.isContactRecipient -> ExpirationType.DELETE_AFTER_READ
|
||||
recipient.isGroupRecipient -> ExpirationType.DELETE_AFTER_SEND
|
||||
recipient.isContactRecipient -> ExpiryMode.AfterRead(message.duration!!.toLong())
|
||||
recipient.isGroupRecipient -> ExpiryMode.AfterSend(message.duration!!.toLong())
|
||||
else -> null
|
||||
}
|
||||
try {
|
||||
@@ -167,12 +169,16 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
|
||||
threadId = module.storage.getOrCreateThreadIdFor(fromSerialized(doubleEncodeGroupID(message.groupPublicKey!!)))
|
||||
}
|
||||
module.storage.setExpirationConfiguration(
|
||||
ExpirationConfiguration(threadId, message.duration!!, type?.number ?: -1, System.currentTimeMillis())
|
||||
ExpirationConfiguration(
|
||||
threadId,
|
||||
type,
|
||||
SnodeAPI.nowWithOffset
|
||||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e("Loki", "Failed to update expiration configuration.")
|
||||
}
|
||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.number ?: -1)
|
||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type)
|
||||
}
|
||||
|
||||
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {
|
||||
@@ -270,23 +276,30 @@ fun handleMessageRequestResponse(message: MessageRequestResponse) {
|
||||
}
|
||||
//endregion
|
||||
|
||||
fun MessageReceiver.updateExpiryIfNeeded(message: Message, proto: SignalServiceProtos.Content, openGroupID: String?, lastSeen: Long) {
|
||||
fun MessageReceiver.updateExpiryIfNeeded(
|
||||
message: Message,
|
||||
proto: SignalServiceProtos.Content,
|
||||
openGroupID: String?
|
||||
) {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
|
||||
val sentTime = message.sentTimestamp ?: throw MessageReceiver.Error.InvalidMessage
|
||||
if (!proto.hasLastDisappearingMessageChangeTimestamp()) return
|
||||
val threadID = storage.getThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID, false)
|
||||
if (threadID == null) throw MessageReceiver.Error.NoThread
|
||||
val threadID =
|
||||
storage.getThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID, false)
|
||||
?: throw MessageReceiver.Error.NoThread
|
||||
val recipient = storage.getRecipientForThread(threadID) ?: throw MessageReceiver.Error.NoThread
|
||||
|
||||
val localConfig = storage.getExpirationConfiguration(threadID)
|
||||
|
||||
val durationSeconds = if (proto.hasExpirationTimer()) proto.expirationTimer else 0
|
||||
val type = if (proto.hasExpirationType()) proto.expirationType else null
|
||||
|
||||
val expiryMode = type?.expiryMode(durationSeconds.toLong())
|
||||
|
||||
val remoteConfig = ExpirationConfiguration(
|
||||
threadID,
|
||||
durationSeconds,
|
||||
type?.number ?: -1,
|
||||
expiryMode,
|
||||
proto.lastDisappearingMessageChangeTimestamp
|
||||
)
|
||||
|
||||
@@ -312,12 +325,12 @@ fun MessageReceiver.updateExpiryIfNeeded(message: Message, proto: SignalServiceP
|
||||
|
||||
// handle a delete after send expired fetch
|
||||
if (type == ExpirationType.DELETE_AFTER_SEND
|
||||
&& sentTime + configToUse.durationSeconds <= SnodeAPI.nowWithOffset) {
|
||||
&& sentTime + (configToUse.expiryMode?.expirySeconds ?: 0) <= SnodeAPI.nowWithOffset) {
|
||||
throw MessageReceiver.Error.ExpiredMessage
|
||||
}
|
||||
// handle a delete after read last known config value (test) TODO: actually implement this with shared config library
|
||||
// handle a delete after read last known config value
|
||||
if (type == ExpirationType.DELETE_AFTER_READ
|
||||
&& sentTime + configToUse.durationSeconds <= ExpirationConfiguration.LAST_READ_TEST) {
|
||||
&& sentTime + (configToUse.expiryMode?.expirySeconds ?: 0) <= storage.getLastSeen(threadID)) {
|
||||
throw MessageReceiver.Error.ExpiredMessage
|
||||
}
|
||||
|
||||
@@ -326,7 +339,7 @@ fun MessageReceiver.updateExpiryIfNeeded(message: Message, proto: SignalServiceP
|
||||
}
|
||||
|
||||
if (message is ExpirationTimerUpdate) {
|
||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.number ?: -1)
|
||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.expiryMode(durationSeconds.toLong()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package org.session.libsession.messaging.utilities
|
||||
|
||||
import android.content.Context
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.session.libsession.R
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.messaging.calls.CallMessageType
|
||||
@@ -14,7 +15,6 @@ import org.session.libsession.messaging.sending_receiving.data_extraction.DataEx
|
||||
import org.session.libsession.utilities.Address
|
||||
import org.session.libsession.utilities.ExpirationUtil
|
||||
import org.session.libsession.utilities.truncateIdForDisplay
|
||||
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
|
||||
|
||||
object UpdateMessageBuilder {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
@@ -99,9 +99,9 @@ object UpdateMessageBuilder {
|
||||
val time = ExpirationUtil.getExpirationDisplayValue(context, duration.toInt())
|
||||
val threadId = storage.getThreadId(Address.fromSerialized(senderId!!))
|
||||
val config = threadId?.let { storage.getExpirationConfiguration(it) }
|
||||
val state = when (config?.expirationType) {
|
||||
ExpirationType.DELETE_AFTER_SEND -> context.getString(R.string.MessageRecord_state_sent)
|
||||
ExpirationType.DELETE_AFTER_READ -> context.getString(R.string.MessageRecord_state_read)
|
||||
val state = when (config?.expiryMode) {
|
||||
is ExpiryMode.AfterSend -> context.getString(R.string.MessageRecord_state_sent)
|
||||
is ExpiryMode.AfterRead -> context.getString(R.string.MessageRecord_state_read)
|
||||
else -> ""
|
||||
}
|
||||
if (isOutgoing) {
|
||||
|
@@ -2,10 +2,10 @@ package org.session.libsession.utilities;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.session.libsession.R;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ExpirationUtil {
|
||||
|
||||
public static String getExpirationDisplayValue(Context context, int expirationTime) {
|
||||
@@ -28,20 +28,20 @@ public class ExpirationUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getExpirationAbbreviatedDisplayValue(Context context, int expirationTime) {
|
||||
public static String getExpirationAbbreviatedDisplayValue(Context context, long expirationTime) {
|
||||
if (expirationTime < TimeUnit.MINUTES.toSeconds(1)) {
|
||||
return context.getResources().getString(R.string.expiration_seconds_abbreviated, expirationTime);
|
||||
} else if (expirationTime < TimeUnit.HOURS.toSeconds(1)) {
|
||||
int minutes = expirationTime / (int)TimeUnit.MINUTES.toSeconds(1);
|
||||
long minutes = expirationTime / TimeUnit.MINUTES.toSeconds(1);
|
||||
return context.getResources().getString(R.string.expiration_minutes_abbreviated, minutes);
|
||||
} else if (expirationTime < TimeUnit.DAYS.toSeconds(1)) {
|
||||
int hours = expirationTime / (int)TimeUnit.HOURS.toSeconds(1);
|
||||
long hours = expirationTime / TimeUnit.HOURS.toSeconds(1);
|
||||
return context.getResources().getString(R.string.expiration_hours_abbreviated, hours);
|
||||
} else if (expirationTime < TimeUnit.DAYS.toSeconds(7)) {
|
||||
int days = expirationTime / (int)TimeUnit.DAYS.toSeconds(1);
|
||||
long days = expirationTime / TimeUnit.DAYS.toSeconds(1);
|
||||
return context.getResources().getString(R.string.expiration_days_abbreviated, days);
|
||||
} else {
|
||||
int weeks = expirationTime / (int)TimeUnit.DAYS.toSeconds(7);
|
||||
long weeks = expirationTime / TimeUnit.DAYS.toSeconds(7);
|
||||
return context.getResources().getString(R.string.expiration_weeks_abbreviated, weeks);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,29 @@
|
||||
package org.session.libsession.utilities
|
||||
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.session.libsignal.protos.SignalServiceProtos
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
fun ExpiryMode?.typeRadioIndex(): Int {
|
||||
return when (this) {
|
||||
is ExpiryMode.AfterRead -> SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_READ_VALUE
|
||||
is ExpiryMode.AfterSend -> SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_SEND_VALUE
|
||||
else -> -1
|
||||
}
|
||||
}
|
||||
|
||||
fun SignalServiceProtos.Content.ExpirationType?.expiryMode(durationSeconds: Long): ExpiryMode? = when (this) {
|
||||
null -> null
|
||||
SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_READ -> ExpiryMode.AfterRead(durationSeconds)
|
||||
SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_SEND -> ExpiryMode.AfterSend(durationSeconds)
|
||||
SignalServiceProtos.Content.ExpirationType.UNKNOWN -> null
|
||||
}
|
||||
|
||||
fun Int.expiryType(): KClass<out ExpiryMode>? {
|
||||
if (this == -1) return null
|
||||
return when (this) {
|
||||
SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_READ_VALUE -> ExpiryMode.AfterSend::class
|
||||
SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_SEND_VALUE -> ExpiryMode.AfterRead::class
|
||||
else -> ExpiryMode.NONE::class
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package org.session.libsession.utilities
|
||||
|
||||
import android.content.Context
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier
|
||||
@@ -37,7 +38,7 @@ class SSKEnvironment(
|
||||
}
|
||||
|
||||
interface MessageExpirationManagerProtocol {
|
||||
fun setExpirationTimer(message: ExpirationTimerUpdate, expiryType: Int)
|
||||
fun setExpirationTimer(message: ExpirationTimerUpdate, expiryType: ExpiryMode?)
|
||||
fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user