diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt index b9b5d3c3c3..ec31c25bd7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt @@ -4,6 +4,7 @@ import android.content.Context import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.ConversationVolatileConfig +import network.loki.messenger.libsession_util.UserGroupsConfig import network.loki.messenger.libsession_util.UserProfile import org.session.libsession.utilities.ConfigFactoryProtocol import org.session.libsession.utilities.ConfigFactoryUpdateListener @@ -34,7 +35,8 @@ class ConfigFactory(private val context: Context, private val contactsHashes = ConcurrentSkipListSet() private val convoVolatileLock = Object() private var _convoVolatileConfig: ConversationVolatileConfig? = null - private val convoHashes = ConcurrentSkipListSet() + private val userGroupsLock = Object() + private var _userGroups: UserGroupsConfig? = null private val listeners: MutableList = mutableListOf() fun registerListener(listener: ConfigFactoryUpdateListener) { listeners += listener } @@ -77,7 +79,6 @@ class ConfigFactory(private val context: Context, _convoVolatileConfig = if (convoDump != null) { ConversationVolatileConfig.newInstance(secretKey, convoDump) } else { - // TODO: generate convo volatile config here ConfigurationMessageUtilities.generateConversationVolatileDump(context)?.let { dump -> ConversationVolatileConfig.newInstance(secretKey, dump) } ?: ConversationVolatileConfig.newInstance(secretKey) @@ -86,6 +87,21 @@ class ConfigFactory(private val context: Context, _convoVolatileConfig } + override val userGroups: UserGroupsConfig? get() = synchronized(userGroupsLock) { + if (_userGroups == null) { + val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null + val userGroupsDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.GROUPS.name, publicKey) + _userGroups = if (userGroupsDump != null) { + UserGroupsConfig.Companion.newInstance(secretKey, userGroupsDump) + } else { + ConfigurationMessageUtilities.generateUserGroupDump(context)?.let { dump -> + UserGroupsConfig.Companion.newInstance(secretKey, dump) + } ?: UserGroupsConfig.newInstance(secretKey) + } + } + _userGroups + } + private fun persistUserConfigDump() = synchronized(userLock) { val dumped = user?.dump() ?: return @@ -105,6 +121,12 @@ class ConfigFactory(private val context: Context, configDatabase.storeConfig(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey, dumped) } + private fun persistUserGroupsConfigDump() = synchronized(userGroupsLock) { + val dumped = userGroups?.dump() ?: return + val (_, publicKey) = maybeGetUserInfo() ?: return + configDatabase.storeConfig(SharedConfigMessage.Kind.GROUPS.name, publicKey, dumped) + } + override fun persist(forConfigObject: ConfigBase) { listeners.forEach { listener -> listener.notifyUpdates(forConfigObject) @@ -113,6 +135,7 @@ class ConfigFactory(private val context: Context, is UserProfile -> persistUserConfigDump() is Contacts -> persistContactsConfigDump() is ConversationVolatileConfig -> persistConvoVolatileConfigDump() + is UserGroupsConfig -> persistUserGroupsConfigDump() else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet") } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt index a4a75e644d..0850ba1f75 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt @@ -194,7 +194,6 @@ object ConfigurationMessageUtilities { } recipient.isContactRecipient -> { val sessionId = SessionId(recipient.address.serialize()) - if (recipient.isLocalNumber) null // this is handled by the user profile NTS data else convoConfig.getOrConstructOneToOne(recipient.address.serialize()) } @@ -237,7 +236,6 @@ object ConfigurationMessageUtilities { val sessionId = GroupUtil.doubleEncodeGroupID(group.getId()) val admins = group.admins.map { it.serialize() to true }.toMap() val members = group.members.filterNot { it.serialize() !in admins.keys }.map { it.serialize() to false }.toMap() - val encPub = storage.getClosedGroupEncryptionKeyPairs(group.) GroupInfo.LegacyGroupInfo( sessionId = sessionId, name = group.title, @@ -248,7 +246,6 @@ object ConfigurationMessageUtilities { encSecKey = encryptionKeyPair.privateKey.serialize() ) } - (allOpenGroups + allLgc).forEach { groupInfo -> groupConfig.set(groupInfo) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index d3c2dc5ae6..21016f6640 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.runBlocking import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.ConversationVolatileConfig +import network.loki.messenger.libsession_util.UserGroupsConfig import network.loki.messenger.libsession_util.UserProfile import nl.komponents.kovenant.Deferred import nl.komponents.kovenant.Promise @@ -175,7 +176,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti requestSparseArray[personalMessages.namespace!!] = personalMessages } // get the latest convo info volatile - listOfNotNull(configFactory.user, configFactory.contacts, configFactory.convoVolatile).mapNotNull { config -> + configFactory.getUserConfigs().mapNotNull { config -> SnodeAPI.buildAuthenticatedRetrieveBatchRequest( snode, userPublicKey, config.configNamespace() @@ -236,6 +237,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti UserProfile::class.java -> processConfig(snode, body, key, configFactory.user) Contacts::class.java -> processConfig(snode, body, key, configFactory.contacts) ConversationVolatileConfig::class.java -> processConfig(snode, body, key, configFactory.convoVolatile) + UserGroupsConfig::class.java -> processConfig(snode, body, key, configFactory.userGroups) } } } diff --git a/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt b/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt index 0997e88a79..160666d158 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt @@ -3,12 +3,15 @@ package org.session.libsession.utilities import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.ConversationVolatileConfig +import network.loki.messenger.libsession_util.UserGroupsConfig import network.loki.messenger.libsession_util.UserProfile interface ConfigFactoryProtocol { val user: UserProfile? val contacts: Contacts? val convoVolatile: ConversationVolatileConfig? + val userGroups: UserGroupsConfig? + fun getUserConfigs(): List fun persist(forConfigObject: ConfigBase) }