From 2f2ebe945180f62ac41b97e0136d17b60dac49a4 Mon Sep 17 00:00:00 2001 From: 0x330a <92654767+0x330a@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:29:29 +1100 Subject: [PATCH] feat: add basic message read logic for synchronizing last reads, need to modify the query to use the last seen instead of the unread count in a subquery possibly for thread display record --- .../securesms/ApplicationContext.java | 9 +- .../securesms/database/MmsDatabase.kt | 7 ++ .../securesms/database/SmsDatabase.java | 3 + .../securesms/database/Storage.kt | 112 +++++++++++++++++- .../securesms/database/ThreadDatabase.java | 21 ++++ .../securesms/dependencies/ConfigFactory.kt | 62 ++-------- .../securesms/dependencies/DatabaseModule.kt | 3 +- .../dependencies/SessionUtilModule.kt | 8 +- .../securesms/preferences/SettingsActivity.kt | 8 +- .../repository/ConversationRepository.kt | 4 +- .../libsession/database/StorageProtocol.kt | 6 + .../sending_receiving/pollers/Poller.kt | 1 - .../utilities/ConfigFactoryProtocol.kt | 5 +- .../session/libsession/utilities/GroupUtil.kt | 7 +- 14 files changed, 189 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index b0d4a9cf9f..efb72bd5e7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -40,6 +40,7 @@ import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPol import org.session.libsession.messaging.sending_receiving.pollers.Poller; import org.session.libsession.snode.SnodeModule; import org.session.libsession.utilities.Address; +import org.session.libsession.utilities.ConfigFactoryUpdateListener; import org.session.libsession.utilities.ProfilePictureUtilities; import org.session.libsession.utilities.SSKEnvironment; import org.session.libsession.utilities.TextSecurePreferences; @@ -115,6 +116,7 @@ import dagger.hilt.android.HiltAndroidApp; import kotlin.Unit; import kotlinx.coroutines.Job; import network.loki.messenger.BuildConfig; +import network.loki.messenger.libsession_util.ConfigBase; /** * Will be called once when the TextSecure process is created. @@ -125,7 +127,7 @@ import network.loki.messenger.BuildConfig; * @author Moxie Marlinspike */ @HiltAndroidApp -public class ApplicationContext extends Application implements DefaultLifecycleObserver { +public class ApplicationContext extends Application implements DefaultLifecycleObserver, ConfigFactoryUpdateListener { public static final String PREFERENCES_NAME = "SecureSMS-Preferences"; @@ -199,6 +201,11 @@ public class ApplicationContext extends Application implements DefaultLifecycleO return this.persistentLogger; } + @Override + public void notifyUpdates(@NonNull ConfigBase forConfigObject) { + // forward to the config factory / storage ig + storage.notifyConfigUpdates(forConfigObject); + } @Override public void onCreate() { DatabaseModule.init(this); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt index f0b849ef0c..4f4dbc9821 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt @@ -399,6 +399,13 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa database.update(TABLE_NAME, contentValues, ID_WHERE, arrayOf(id.toString())) } + fun setMessagesRead(threadId: Long, beforeTime: Long): List { + return setMessagesRead( + THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1) AND " + DATE_RECEIVED + " <= ?", + arrayOf(threadId.toString(), beforeTime.toString()) + ) + } + fun setMessagesRead(threadId: Long): List { return setMessagesRead( THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1)", diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index a5014aacb8..6b9c7b3d34 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -321,6 +321,9 @@ public class SmsDatabase extends MessagingDatabase { } } + public List setMessagesRead(long threadId, long beforeTime) { + return setMessagesRead(THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1) AND " + DATE_RECEIVED + " <= ?", new String[]{threadId+"", beforeTime+""}); + } public List setMessagesRead(long threadId) { return setMessagesRead(THREAD_ID + " = ? AND (" + READ + " = 0 OR " + REACTIONS_UNREAD + " = 1)", new String[] {String.valueOf(threadId)}); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 05eb1b468a..70893c9d55 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -2,6 +2,11 @@ package org.thoughtcrime.securesms.database import android.content.Context import android.net.Uri +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.UserProfile +import network.loki.messenger.libsession_util.util.Conversation import org.session.libsession.avatars.AvatarHelper import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.BlindedIdMapping @@ -52,21 +57,26 @@ import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.crypto.ecc.ECKeyPair import org.session.libsignal.messages.SignalServiceAttachmentPointer import org.session.libsignal.messages.SignalServiceGroup +import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.KeyHelper +import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.guava.Optional import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.ReactionRecord +import org.thoughtcrime.securesms.dependencies.ConfigFactory import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.groups.OpenGroupManager import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob import org.thoughtcrime.securesms.mms.PartAuthority +import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities import org.thoughtcrime.securesms.util.SessionMetaProtocol import java.security.MessageDigest +import network.loki.messenger.libsession_util.util.Contact as LibSessionContact -class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), StorageProtocol { +class Storage(context: Context, helper: SQLCipherOpenHelper, private val configFactory: ConfigFactory) : Database(context, helper), StorageProtocol { override fun getUserPublicKey(): String? { return TextSecurePreferences.getLocalNumber(context) @@ -262,6 +272,81 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, return DatabaseComponent.get(context).lokiAPIDatabase().getAuthToken(id) } + override fun notifyConfigUpdates(forConfigObject: ConfigBase) { + notifyUpdates(forConfigObject) + } + + fun notifyUpdates(forConfigObject: ConfigBase) { + when (forConfigObject) { + is UserProfile -> updateUser(forConfigObject) + is Contacts -> updateContacts(forConfigObject) + is ConversationVolatileConfig -> updateConvoVolatile(forConfigObject) + } + } + + private fun updateUser(userProfile: UserProfile) { + val userPublicKey = getUserPublicKey() ?: return + // would love to get rid of recipient and context from this + val recipient = Recipient.from(context, fromSerialized(userPublicKey), false) + // update name + val name = userProfile.getName() ?: return + val userPic = userProfile.getPic() + val profileManager = SSKEnvironment.shared.profileManager + if (name.isNotEmpty()) { + TextSecurePreferences.setProfileName(context, name) + profileManager.setName(context, recipient, name) + } + + // update pfp + if (userPic == null) { + // clear picture if userPic is null + TextSecurePreferences.setProfileKey(context, null) + ProfileKeyUtil.setEncodedProfileKey(context, null) + profileManager.setProfileKey(context, recipient, null) + setUserProfilePictureURL(null) + } else if (userPic.key.isNotEmpty() && userPic.url.isNotEmpty() + && TextSecurePreferences.getProfilePictureURL(context) != userPic.url) { + val profileKey = Base64.encodeBytes(userPic.key) + ProfileKeyUtil.setEncodedProfileKey(context, profileKey) + profileManager.setProfileKey(context, recipient, userPic.key) + setUserProfilePictureURL(userPic.url) + } + } + + private fun updateContacts(contacts: Contacts) { + val extracted = contacts.all().toList() + extracted.forEach { contact -> + val address = Address.fromSerialized(contact.id) + val settings = getRecipientSettings(address) ?: run { + // new contact, store it + } + contact.name + contact.approved + contact.approvedMe + contact.blocked + contact.nickname + contact.profilePicture + } + } + + private fun updateConvoVolatile(convos: ConversationVolatileConfig) { + val extracted = convos.all() + for (conversation in extracted) { + val threadId = when (conversation) { + is Conversation.OneToOne -> conversation.sessionId.let { + getOrCreateThreadIdFor(fromSerialized(it)) + } + is Conversation.LegacyClosedGroup -> conversation.groupId.let { + getOrCreateThreadIdFor("", it,null) + } + is Conversation.OpenGroup -> conversation.baseUrl.let { + getOrCreateThreadIdFor("",null, it) + } + } + Log.d("Loki-DBG", "Should update thread $threadId") + } + } + override fun setAuthToken(room: String, server: String, newValue: String) { val id = "$server.$room" DatabaseComponent.get(context).lokiAPIDatabase().setAuthToken(id, newValue) @@ -455,6 +540,12 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, override fun createGroup(groupId: String, title: String?, members: List
, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List
, formationTimestamp: Long) { DatabaseComponent.get(context).groupDatabase().create(groupId, title, members, avatar, relay, admins, formationTimestamp) + val volatiles = configFactory.convoVolatile ?: return + val groupPublicKey = GroupUtil.doubleDecodeGroupId(groupId) + val groupVolatileConfig = volatiles.getOrConstructLegacyClosedGroup(groupPublicKey) + groupVolatileConfig.lastRead = formationTimestamp + volatiles.set(groupVolatileConfig) + ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context) } override fun isGroupActive(groupPublicKey: String): Boolean { @@ -660,6 +751,25 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, return if (recipientSettings.isPresent) { recipientSettings.get() } else null } + override fun addLibSessionContacts(contacts: List) { + val recipientDatabase = DatabaseComponent.get(context).recipientDatabase() + val threadDatabase = DatabaseComponent.get(context).threadDatabase() + val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase() + val moreContacts = contacts.filter { contact -> + val id = SessionId(contact.id) + id.prefix != IdPrefix.BLINDED || mappingDb.getBlindedIdMapping(contact.id).none { it.sessionId != null } + } + for (contact in moreContacts) { + val address = fromSerialized(contact.id) + val recipient = Recipient.from(context, address, true) + val (url, key) = contact.profilePicture?.let { it.url to it.key } ?: (null to null) + // set or clear the avatar + recipientDatabase.setProfileAvatar(recipient, url) + recipientDatabase.setProfileKey(recipient, key) + + } + } + override fun addContacts(contacts: List) { val recipientDatabase = DatabaseComponent.get(context).recipientDatabase() val threadDatabase = DatabaseComponent.get(context).threadDatabase() diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index 26b20ab00a..79f675bc2e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -295,6 +295,27 @@ public class ThreadDatabase extends Database { notifyConversationListeners(threadId); } + public List setRead(long threadId, long lastReadTime) { + ContentValues contentValues = new ContentValues(1); + contentValues.put(READ, 1); + contentValues.put(UNREAD_COUNT, 0); + contentValues.put(UNREAD_MENTION_COUNT, 0); + contentValues.put(LAST_SEEN, lastReadTime); + + SQLiteDatabase db = databaseHelper.getWritableDatabase(); + db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""}); + + final List smsRecords = DatabaseComponent.get(context).smsDatabase().setMessagesRead(threadId, lastReadTime); + final List mmsRecords = DatabaseComponent.get(context).mmsDatabase().setMessagesRead(threadId, lastReadTime); + + notifyConversationListListeners(); + + return new LinkedList() {{ + addAll(smsRecords); + addAll(mmsRecords); + }}; + } + public List setRead(long threadId, boolean lastSeen) { ContentValues contentValues = new ContentValues(1); contentValues.put(READ, 1); 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 afff87aaae..dfbb82bc26 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt @@ -5,21 +5,14 @@ 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.UserProfile -import org.session.libsession.database.StorageProtocol -import org.session.libsession.utilities.Address import org.session.libsession.utilities.ConfigFactoryProtocol -import org.session.libsession.utilities.ProfileKeyUtil -import org.session.libsession.utilities.SSKEnvironment -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.recipients.Recipient +import org.session.libsession.utilities.ConfigFactoryUpdateListener import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage -import org.session.libsignal.utilities.Base64 import org.thoughtcrime.securesms.database.ConfigDatabase import java.util.concurrent.ConcurrentSkipListSet class ConfigFactory(private val context: Context, private val configDatabase: ConfigDatabase, - private val storage: StorageProtocol, private val maybeGetUserInfo: ()->Pair?): ConfigFactoryProtocol { @@ -42,6 +35,10 @@ class ConfigFactory(private val context: Context, private var _convoVolatileConfig: ConversationVolatileConfig? = null private val convoHashes = ConcurrentSkipListSet() + private val listeners: MutableList = mutableListOf() + fun registerListener(listener: ConfigFactoryUpdateListener) { listeners += listener } + fun unregisterListener(listener: ConfigFactoryUpdateListener) { listeners -= listener } + override val user: UserProfile? = synchronized(userLock) { if (_userConfig == null) { val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null @@ -115,6 +112,9 @@ class ConfigFactory(private val context: Context, is Contacts -> persistContactsConfigDump() is ConversationVolatileConfig -> persistConvoVolatileConfigDump() } + listeners.forEach { listener -> + listener.notifyUpdates(forConfigObject) + } } override fun appendHash(configObject: ConfigBase, hash: String) { @@ -125,14 +125,6 @@ class ConfigFactory(private val context: Context, } } - override fun notifyUpdates(forConfigObject: ConfigBase) { - when (forConfigObject) { - is UserProfile -> updateUser(forConfigObject) - is Contacts -> updateContacts(forConfigObject) - is ConversationVolatileConfig -> updateConvoVolatile(forConfigObject) - } - } - override fun getHashesFor(forConfigObject: ConfigBase): List = when (forConfigObject) { is UserProfile -> userHashes.toList() @@ -147,42 +139,4 @@ class ConfigFactory(private val context: Context, is ConversationVolatileConfig -> convoHashes.removeAll(deletedHashes) } - private fun updateUser(userProfile: UserProfile) { - val (_, userPublicKey) = maybeGetUserInfo() ?: return - // would love to get rid of recipient and context from this - val recipient = Recipient.from(context, Address.fromSerialized(userPublicKey), false) - // update name - val name = userProfile.getName() ?: return - val userPic = userProfile.getPic() - val profileManager = SSKEnvironment.shared.profileManager - if (name.isNotEmpty()) { - TextSecurePreferences.setProfileName(context, name) - profileManager.setName(context, recipient, name) - } - - // update pfp - if (userPic == null) { - // clear picture if userPic is null - TextSecurePreferences.setProfileKey(context, null) - ProfileKeyUtil.setEncodedProfileKey(context, null) - profileManager.setProfileKey(context, recipient, null) - storage.setUserProfilePictureURL(null) - } else if (userPic.key.isNotEmpty() && userPic.url.isNotEmpty() - && TextSecurePreferences.getProfilePictureURL(context) != userPic.url) { - val profileKey = Base64.encodeBytes(userPic.key) - ProfileKeyUtil.setEncodedProfileKey(context, profileKey) - profileManager.setProfileKey(context, recipient, userPic.key) - storage.setUserProfilePictureURL(userPic.url) - } - } - - private fun updateContacts(contacts: Contacts) { - - } - - private fun updateConvoVolatile(convos: ConversationVolatileConfig) { - - } - - } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt index edd246984d..8fe656682e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt @@ -6,7 +6,6 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import net.zetetic.database.sqlcipher.SQLiteDatabase import org.session.libsession.database.MessageDataProvider import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider import org.thoughtcrime.securesms.crypto.AttachmentSecret @@ -136,7 +135,7 @@ object DatabaseModule { @Provides @Singleton - fun provideStorage(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = Storage(context,openHelper) + fun provideStorage(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper, configFactory: ConfigFactory) = Storage(context,openHelper, configFactory) @Provides @Singleton diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SessionUtilModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/SessionUtilModule.kt index 7dc45cfc90..cd4b071338 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SessionUtilModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/SessionUtilModule.kt @@ -6,10 +6,10 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent +import org.session.libsession.utilities.ConfigFactoryUpdateListener import org.session.libsession.utilities.TextSecurePreferences import org.thoughtcrime.securesms.crypto.KeyPairUtilities import org.thoughtcrime.securesms.database.ConfigDatabase -import org.thoughtcrime.securesms.database.Storage import javax.inject.Singleton @Module @@ -23,12 +23,14 @@ object SessionUtilModule { @Provides @Singleton - fun provideConfigFactory(@ApplicationContext context: Context, configDatabase: ConfigDatabase, storage: Storage): ConfigFactory = - ConfigFactory(context, configDatabase, storage) { + fun provideConfigFactory(@ApplicationContext context: Context, configDatabase: ConfigDatabase): ConfigFactory = + ConfigFactory(context, configDatabase) { val localUserPublicKey = TextSecurePreferences.getLocalNumber(context) val secretKey = maybeUserEdSecretKey(context) if (localUserPublicKey == null || secretKey == null) null else secretKey to localUserPublicKey + }.apply { + registerListener(context as ConfigFactoryUpdateListener) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt index 4839180265..c7390683c1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt @@ -213,6 +213,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { } val compoundPromise = all(promises) compoundPromise.successUi { // Do this on the UI thread so that it happens before the alwaysUi clause below + val userConfig = configFactory.user if (isUpdatingProfilePicture && profilePicture != null) { AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture) TextSecurePreferences.setProfileAvatarId(this, SecureRandom().nextInt()) @@ -220,11 +221,14 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { // new config val url = TextSecurePreferences.getProfilePictureURL(this) val profileKey = ProfileKeyUtil.getProfileKey(this) - if (!url.isNullOrEmpty() && !profileKey.isEmpty()) { - configFactory.user?.setPic(UserPic(url, profileKey)) + if (!url.isNullOrEmpty() && profileKey.isNotEmpty()) { + userConfig?.setPic(UserPic(url, profileKey)) } } if (profilePicture != null || displayName != null) { + if (userConfig != null && userConfig.needsDump()) { + configFactory.persist(userConfig) + } ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@SettingsActivity) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt index 2d67894011..66b64480c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt @@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.database.SmsDatabase import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.ThreadRecord +import org.thoughtcrime.securesms.dependencies.ConfigFactory import javax.inject.Inject import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException @@ -83,7 +84,8 @@ class DefaultConversationRepository @Inject constructor( private val mmsSmsDb: MmsSmsDatabase, private val recipientDb: RecipientDatabase, private val lokiMessageDb: LokiMessageDatabase, - private val sessionJobDb: SessionJobDatabase + private val sessionJobDb: SessionJobDatabase, + private val configFactory: ConfigFactory ) : ConversationRepository { override fun maybeGetRecipientForThreadId(threadId: Long): Recipient? { diff --git a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt index bdde41817c..8e39b815c7 100644 --- a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt @@ -2,6 +2,7 @@ package org.session.libsession.database import android.content.Context import android.net.Uri +import network.loki.messenger.libsession_util.ConfigBase import org.session.libsession.messaging.BlindedIdMapping import org.session.libsession.messaging.calls.CallMessageType import org.session.libsession.messaging.contacts.Contact @@ -31,6 +32,7 @@ import org.session.libsession.utilities.recipients.Recipient.RecipientSettings import org.session.libsignal.crypto.ecc.ECKeyPair import org.session.libsignal.messages.SignalServiceAttachmentPointer import org.session.libsignal.messages.SignalServiceGroup +import network.loki.messenger.libsession_util.util.Contact as LibSessionContact interface StorageProtocol { @@ -164,6 +166,7 @@ interface StorageProtocol { fun setContact(contact: Contact) fun getRecipientForThread(threadId: Long): Recipient? fun getRecipientSettings(address: Address): RecipientSettings? + fun addLibSessionContacts(contacts: List) fun addContacts(contacts: List) // Attachments @@ -202,4 +205,7 @@ interface StorageProtocol { fun deleteReactions(messageId: Long, mms: Boolean) fun unblock(toUnblock: List) fun blockedContacts(): List + + // Shared configs + fun notifyConfigUpdates(forConfigObject: ConfigBase) } 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 a699cb9218..bd06e292a0 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 @@ -161,7 +161,6 @@ class Poller(private val configFactory: ConfigFactoryProtocol) { } // process new results configFactory.persist(forConfigObject) - configFactory.notifyUpdates(forConfigObject) } private fun poll(snode: Snode, deferred: Deferred): Promise { 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 b05496c828..8cdb2b34ee 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt @@ -11,7 +11,10 @@ interface ConfigFactoryProtocol { val convoVolatile: ConversationVolatileConfig? fun persist(forConfigObject: ConfigBase) fun appendHash(configObject: ConfigBase, hash: String) - fun notifyUpdates(forConfigObject: ConfigBase) fun getHashesFor(forConfigObject: ConfigBase): List fun removeHashesFor(config: ConfigBase, deletedHashes: Set): Boolean +} + +interface ConfigFactoryUpdateListener { + fun notifyUpdates(forConfigObject: ConfigBase) } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt b/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt index 3458e06eb6..3f1563e3d1 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt @@ -3,7 +3,6 @@ package org.session.libsession.utilities import org.session.libsignal.messages.SignalServiceGroup import org.session.libsignal.utilities.Hex import java.io.IOException -import kotlin.jvm.Throws object GroupUtil { const val CLOSED_GROUP_PREFIX = "__textsecure_group__!" @@ -97,4 +96,10 @@ object GroupUtil { fun doubleDecodeGroupID(groupID: String): ByteArray { return getDecodedGroupIDAsData(getDecodedGroupID(groupID)) } + + @JvmStatic + @Throws(IOException::class) + fun doubleDecodeGroupId(groupID: String): String { + return Hex.toStringCondensed(getDecodedGroupIDAsData(getDecodedGroupID(groupID))) + } } \ No newline at end of file