mirror of
				https://github.com/oxen-io/session-android.git
				synced 2025-10-31 17:59:40 +00:00 
			
		
		
		
	feat: incorporate hashes from library, more wrapper for user groups and serialization from c++
This commit is contained in:
		| @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.database | |||||||
| import android.content.Context | import android.content.Context | ||||||
| import androidx.core.content.contentValuesOf | import androidx.core.content.contentValuesOf | ||||||
| import androidx.core.database.getBlobOrNull | import androidx.core.database.getBlobOrNull | ||||||
| import androidx.core.database.getStringOrNull |  | ||||||
| import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper | import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper | ||||||
|  |  | ||||||
| class ConfigDatabase(context: Context, helper: SQLCipherOpenHelper): Database(context, helper) { | class ConfigDatabase(context: Context, helper: SQLCipherOpenHelper): Database(context, helper) { | ||||||
| @@ -12,35 +11,32 @@ class ConfigDatabase(context: Context, helper: SQLCipherOpenHelper): Database(co | |||||||
|         private const val VARIANT = "variant" |         private const val VARIANT = "variant" | ||||||
|         private const val PUBKEY = "publicKey" |         private const val PUBKEY = "publicKey" | ||||||
|         private const val DATA = "data" |         private const val DATA = "data" | ||||||
|         private const val COMBINED_MESSAGE_HASHES = "combined_message_hashes" |  | ||||||
|  |  | ||||||
|         private const val TABLE_NAME = "configs_table" |         private const val TABLE_NAME = "configs_table" | ||||||
|  |  | ||||||
|         const val CREATE_CONFIG_TABLE_COMMAND = |         const val CREATE_CONFIG_TABLE_COMMAND = | ||||||
|             "CREATE TABLE $TABLE_NAME ($VARIANT TEXT NOT NULL, $PUBKEY TEXT NOT NULL, $DATA BLOB, $COMBINED_MESSAGE_HASHES TEXT, PRIMARY KEY($VARIANT, $PUBKEY));" |             "CREATE TABLE $TABLE_NAME ($VARIANT TEXT NOT NULL, $PUBKEY TEXT NOT NULL, $DATA BLOB, PRIMARY KEY($VARIANT, $PUBKEY));" | ||||||
|  |  | ||||||
|         private const val VARIANT_AND_PUBKEY_WHERE = "$VARIANT = ? AND $PUBKEY = ?" |         private const val VARIANT_AND_PUBKEY_WHERE = "$VARIANT = ? AND $PUBKEY = ?" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun storeConfig(variant: String, publicKey: String, data: ByteArray, hashes: List<String>) { |     fun storeConfig(variant: String, publicKey: String, data: ByteArray) { | ||||||
|         val db = writableDatabase |         val db = writableDatabase | ||||||
|         val contentValues = contentValuesOf( |         val contentValues = contentValuesOf( | ||||||
|             VARIANT to variant, |             VARIANT to variant, | ||||||
|             PUBKEY to publicKey, |             PUBKEY to publicKey, | ||||||
|             DATA to data, |             DATA to data, | ||||||
|             COMBINED_MESSAGE_HASHES to hashes.joinToString(",") |  | ||||||
|         ) |         ) | ||||||
|         db.insertOrUpdate(TABLE_NAME, contentValues, VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey)) |         db.insertOrUpdate(TABLE_NAME, contentValues, VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun retrieveConfigAndHashes(variant: String, publicKey: String): Pair<ByteArray,List<String>>? { |     fun retrieveConfigAndHashes(variant: String, publicKey: String): ByteArray? { | ||||||
|         val db = readableDatabase |         val db = readableDatabase | ||||||
|         val query = db.query(TABLE_NAME, arrayOf(DATA, COMBINED_MESSAGE_HASHES), VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey),null, null, null) |         val query = db.query(TABLE_NAME, arrayOf(DATA), VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey),null, null, null) | ||||||
|         return query?.use { cursor -> |         return query?.use { cursor -> | ||||||
|             if (!cursor.moveToFirst()) return@use null |             if (!cursor.moveToFirst()) return@use null | ||||||
|             val bytes = cursor.getBlobOrNull(cursor.getColumnIndex(DATA)) ?: return@use null |             val bytes = cursor.getBlobOrNull(cursor.getColumnIndex(DATA)) ?: return@use null | ||||||
|             val hashes = cursor.getStringOrNull(cursor.getColumnIndex(COMBINED_MESSAGE_HASHES))?.split(",") ?: emptyList() |             bytes | ||||||
|             bytes to hashes |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -47,10 +47,7 @@ class ConfigFactory(private val context: Context, | |||||||
|             Log.d("Loki-DBG", "Getting user configs and hashes") |             Log.d("Loki-DBG", "Getting user configs and hashes") | ||||||
|             val userDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.USER_PROFILE.name, publicKey) |             val userDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.USER_PROFILE.name, publicKey) | ||||||
|             _userConfig = if (userDump != null) { |             _userConfig = if (userDump != null) { | ||||||
|                 val (bytes, hashes) = userDump |                 UserProfile.newInstance(secretKey, userDump) | ||||||
|                 userHashes.clear() |  | ||||||
|                 userHashes.addAll(hashes) |  | ||||||
|                 UserProfile.newInstance(secretKey, bytes) |  | ||||||
|             } else { |             } else { | ||||||
|                 UserProfile.newInstance(secretKey) |                 UserProfile.newInstance(secretKey) | ||||||
|             } |             } | ||||||
| @@ -63,10 +60,7 @@ class ConfigFactory(private val context: Context, | |||||||
|             val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null |             val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null | ||||||
|             val contactsDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.CONTACTS.name, publicKey) |             val contactsDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.CONTACTS.name, publicKey) | ||||||
|             _contacts = if (contactsDump != null) { |             _contacts = if (contactsDump != null) { | ||||||
|                 val (bytes, hashes) = contactsDump |                 Contacts.newInstance(secretKey, contactsDump) | ||||||
|                 contactsHashes.clear() |  | ||||||
|                 contactsHashes.addAll(hashes) |  | ||||||
|                 Contacts.newInstance(secretKey, bytes) |  | ||||||
|             } else { |             } else { | ||||||
|                 Contacts.newInstance(secretKey) |                 Contacts.newInstance(secretKey) | ||||||
|             } |             } | ||||||
| @@ -79,10 +73,7 @@ class ConfigFactory(private val context: Context, | |||||||
|             val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null |             val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null | ||||||
|             val convoDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey) |             val convoDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey) | ||||||
|             _convoVolatileConfig = if (convoDump != null) { |             _convoVolatileConfig = if (convoDump != null) { | ||||||
|                 val (bytes, hashes) = convoDump |                 ConversationVolatileConfig.newInstance(secretKey, convoDump) | ||||||
|                 convoHashes.clear() |  | ||||||
|                 convoHashes.addAll(hashes) |  | ||||||
|                 ConversationVolatileConfig.newInstance(secretKey, bytes) |  | ||||||
|             } else { |             } else { | ||||||
|                 ConversationVolatileConfig.newInstance(secretKey) |                 ConversationVolatileConfig.newInstance(secretKey) | ||||||
|             } |             } | ||||||
| @@ -94,19 +85,19 @@ class ConfigFactory(private val context: Context, | |||||||
|     private fun persistUserConfigDump() = synchronized(userLock) { |     private fun persistUserConfigDump() = synchronized(userLock) { | ||||||
|         val dumped = user?.dump() ?: return |         val dumped = user?.dump() ?: return | ||||||
|         val (_, publicKey) = maybeGetUserInfo() ?: return |         val (_, publicKey) = maybeGetUserInfo() ?: return | ||||||
|         configDatabase.storeConfig(SharedConfigMessage.Kind.USER_PROFILE.name, publicKey, dumped, userHashes.toList()) |         configDatabase.storeConfig(SharedConfigMessage.Kind.USER_PROFILE.name, publicKey, dumped) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun persistContactsConfigDump() = synchronized(contactsLock) { |     private fun persistContactsConfigDump() = synchronized(contactsLock) { | ||||||
|         val dumped = contacts?.dump() ?: return |         val dumped = contacts?.dump() ?: return | ||||||
|         val (_, publicKey) = maybeGetUserInfo() ?: return |         val (_, publicKey) = maybeGetUserInfo() ?: return | ||||||
|         configDatabase.storeConfig(SharedConfigMessage.Kind.CONTACTS.name, publicKey, dumped, contactsHashes.toList()) |         configDatabase.storeConfig(SharedConfigMessage.Kind.CONTACTS.name, publicKey, dumped) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun persistConvoVolatileConfigDump() = synchronized (convoVolatileLock) { |     private fun persistConvoVolatileConfigDump() = synchronized (convoVolatileLock) { | ||||||
|         val dumped = convoVolatile?.dump() ?: return |         val dumped = convoVolatile?.dump() ?: return | ||||||
|         val (_, publicKey) = maybeGetUserInfo() ?: return |         val (_, publicKey) = maybeGetUserInfo() ?: return | ||||||
|         configDatabase.storeConfig(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey, dumped, convoHashes.toList()) |         configDatabase.storeConfig(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey, dumped) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun persist(forConfigObject: ConfigBase) { |     override fun persist(forConfigObject: ConfigBase) { | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import android.content.Context | |||||||
| import network.loki.messenger.libsession_util.util.UserPic | import network.loki.messenger.libsession_util.util.UserPic | ||||||
| import org.session.libsession.messaging.contacts.Contact | import org.session.libsession.messaging.contacts.Contact | ||||||
| import org.session.libsession.utilities.SSKEnvironment | import org.session.libsession.utilities.SSKEnvironment | ||||||
|  | import org.session.libsession.utilities.TextSecurePreferences | ||||||
| import org.session.libsession.utilities.recipients.Recipient | import org.session.libsession.utilities.recipients.Recipient | ||||||
| import org.thoughtcrime.securesms.ApplicationContext | import org.thoughtcrime.securesms.ApplicationContext | ||||||
| import org.thoughtcrime.securesms.dependencies.ConfigFactory | import org.thoughtcrime.securesms.dependencies.ConfigFactory | ||||||
| @@ -84,6 +85,7 @@ class ProfileManager(private val context: Context, private val configFactory: Co | |||||||
|  |  | ||||||
|     override fun contactUpdatedInternal(contact: Contact) { |     override fun contactUpdatedInternal(contact: Contact) { | ||||||
|         val contactConfig = configFactory.contacts ?: return |         val contactConfig = configFactory.contacts ?: return | ||||||
|  |         if (contact.sessionID == TextSecurePreferences.getLocalNumber(context)) return | ||||||
|         contactConfig.upsertContact(contact.sessionID) { |         contactConfig.upsertContact(contact.sessionID) { | ||||||
|             this.name = contact.name.orEmpty() |             this.name = contact.name.orEmpty() | ||||||
|             this.nickname = contact.nickname.orEmpty() |             this.nickname = contact.nickname.orEmpty() | ||||||
|   | |||||||
 Submodule libsession-util/libsession-util updated: c76d7e06f6...5a7569861d
									
								
							| @@ -120,29 +120,18 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_00024Companion_kindFor(J | |||||||
|             return nullptr; |             return nullptr; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| extern "C" |  | ||||||
| JNIEXPORT void JNICALL |  | ||||||
| Java_network_loki_messenger_libsession_1util_ConfigBase_removeObsoleteHashes(JNIEnv *env, |  | ||||||
|                                                                              jobject thiz, |  | ||||||
|                                                                              jobjectArray to_remove) { |  | ||||||
|     auto conf = ptrToConfigBase(env, thiz); |  | ||||||
|     size_t number = env->GetArrayLength(to_remove); |  | ||||||
|     for (int i = 0; i < number; i++) { |  | ||||||
|         auto jElement = (jstring) env->GetObjectArrayElement(to_remove, i); |  | ||||||
|         auto element_as_string = env->GetStringUTFChars(jElement, nullptr); |  | ||||||
|         // TODO: uncomment when this is re-implemented |  | ||||||
| //        conf->confirm_removed(element_as_string); |  | ||||||
|         env->ReleaseStringUTFChars(jElement, element_as_string); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| extern "C" | extern "C" | ||||||
| JNIEXPORT jobject JNICALL | JNIEXPORT jobject JNICALL | ||||||
| Java_network_loki_messenger_libsession_1util_ConfigBase_obsoleteHashes(JNIEnv *env, jobject thiz) { | Java_network_loki_messenger_libsession_1util_ConfigBase_currentHashes(JNIEnv *env, jobject thiz) { | ||||||
|     auto conf = ptrToConfigBase(env, thiz); |     auto conf = ptrToConfigBase(env, thiz); | ||||||
|     jclass stack = env->FindClass("java/util/Stack"); |     jclass stack = env->FindClass("java/util/Stack"); | ||||||
|     jmethodID init = env->GetMethodID(stack, "<init>", "()V"); |     jmethodID init = env->GetMethodID(stack, "<init>", "()V"); | ||||||
|     jobject our_stack = env->NewObject(stack, init); |     jobject our_stack = env->NewObject(stack, init); | ||||||
|     jmethodID push = env->GetMethodID(stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;"); |     jmethodID push = env->GetMethodID(stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;"); | ||||||
|     // TODO: implement obsoleteHashes() |     auto vec = conf->current_hashes(); | ||||||
|  |     for (std::string element: vec) { | ||||||
|  |         env->CallObjectMethod(our_stack, push, env->NewStringUTF(element.data())); | ||||||
|  |     } | ||||||
|     return our_stack; |     return our_stack; | ||||||
| } | } | ||||||
| @@ -14,7 +14,7 @@ inline session::config::Contacts *ptrToContacts(JNIEnv *env, jobject obj) { | |||||||
| inline jobject serialize_contact(JNIEnv *env, session::config::contact_info info) { | inline jobject serialize_contact(JNIEnv *env, session::config::contact_info info) { | ||||||
|     jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact"); |     jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact"); | ||||||
|     jmethodID constructor = env->GetMethodID(contactClass, "<init>", |     jmethodID constructor = env->GetMethodID(contactClass, "<init>", | ||||||
|                                              "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZLnetwork/loki/messenger/libsession_util/util/UserPic;)V"); |                                              "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZLnetwork/loki/messenger/libsession_util/util/UserPic;I)V"); | ||||||
|     jstring id = env->NewStringUTF(info.session_id.data()); |     jstring id = env->NewStringUTF(info.session_id.data()); | ||||||
|     jstring name = env->NewStringUTF(info.name.data()); |     jstring name = env->NewStringUTF(info.name.data()); | ||||||
|     jstring nickname = env->NewStringUTF(info.nickname.data()); |     jstring nickname = env->NewStringUTF(info.nickname.data()); | ||||||
| @@ -23,14 +23,14 @@ inline jobject serialize_contact(JNIEnv *env, session::config::contact_info info | |||||||
|     approvedMe = info.approved_me; |     approvedMe = info.approved_me; | ||||||
|     blocked = info.blocked; |     blocked = info.blocked; | ||||||
|     jobject profilePic = util::serialize_user_pic(env, info.profile_picture); |     jobject profilePic = util::serialize_user_pic(env, info.profile_picture); | ||||||
|     jobject returnObj = env->NewObject(contactClass, constructor, id, name, nickname, approved, approvedMe, blocked, profilePic); |     jobject returnObj = env->NewObject(contactClass, constructor, id, name, nickname, approved, approvedMe, blocked, profilePic, info.priority); | ||||||
|     return returnObj; |     return returnObj; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline session::config::contact_info* deserialize_contact(JNIEnv *env, jobject info) { | inline session::config::contact_info* deserialize_contact(JNIEnv *env, jobject info) { | ||||||
|     jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact"); |     jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact"); | ||||||
|  |  | ||||||
|     jfieldID getId, getName, getNick, getApproved, getApprovedMe, getBlocked, getUserPic; |     jfieldID getId, getName, getNick, getApproved, getApprovedMe, getBlocked, getUserPic, getPriority; | ||||||
|     getId = env->GetFieldID(contactClass, "id", "Ljava/lang/String;"); |     getId = env->GetFieldID(contactClass, "id", "Ljava/lang/String;"); | ||||||
|     getName = env->GetFieldID(contactClass, "name", "Ljava/lang/String;"); |     getName = env->GetFieldID(contactClass, "name", "Ljava/lang/String;"); | ||||||
|     getNick = env->GetFieldID(contactClass, "nickname", "Ljava/lang/String;"); |     getNick = env->GetFieldID(contactClass, "nickname", "Ljava/lang/String;"); | ||||||
| @@ -38,11 +38,13 @@ inline session::config::contact_info* deserialize_contact(JNIEnv *env, jobject i | |||||||
|     getApprovedMe = env->GetFieldID(contactClass, "approvedMe", "Z"); |     getApprovedMe = env->GetFieldID(contactClass, "approvedMe", "Z"); | ||||||
|     getBlocked = env->GetFieldID(contactClass, "blocked", "Z"); |     getBlocked = env->GetFieldID(contactClass, "blocked", "Z"); | ||||||
|     getUserPic = env->GetFieldID(contactClass, "profilePicture", "Lnetwork/loki/messenger/libsession_util/util/UserPic;"); |     getUserPic = env->GetFieldID(contactClass, "profilePicture", "Lnetwork/loki/messenger/libsession_util/util/UserPic;"); | ||||||
|  |     getPriority = env->GetFieldID(contactClass, "priority", "I"); | ||||||
|     jstring name, nickname, session_id; |     jstring name, nickname, session_id; | ||||||
|     session_id = static_cast<jstring>(env->GetObjectField(info, getId)); |     session_id = static_cast<jstring>(env->GetObjectField(info, getId)); | ||||||
|     name = static_cast<jstring>(env->GetObjectField(info, getName)); |     name = static_cast<jstring>(env->GetObjectField(info, getName)); | ||||||
|     nickname = static_cast<jstring>(env->GetObjectField(info, getNick)); |     nickname = static_cast<jstring>(env->GetObjectField(info, getNick)); | ||||||
|     bool approved, approvedMe, blocked; |     bool approved, approvedMe, blocked; | ||||||
|  |     int priority = env->GetIntField(info, getPriority); | ||||||
|     approved = env->GetBooleanField(info, getApproved); |     approved = env->GetBooleanField(info, getApproved); | ||||||
|     approvedMe = env->GetBooleanField(info, getApprovedMe); |     approvedMe = env->GetBooleanField(info, getApprovedMe); | ||||||
|     blocked = env->GetBooleanField(info, getBlocked); |     blocked = env->GetBooleanField(info, getBlocked); | ||||||
| @@ -86,6 +88,8 @@ inline session::config::contact_info* deserialize_contact(JNIEnv *env, jobject i | |||||||
|         env->ReleaseStringUTFChars(nickname, nickname_bytes); |         env->ReleaseStringUTFChars(nickname, nickname_bytes); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     contact_info->priority = priority; | ||||||
|  |  | ||||||
|     return contact_info; |     return contact_info; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,8 +31,6 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_00024Companion_new | |||||||
|     jmethodID constructor = env->GetMethodID(contactsClass, "<init>", "(J)V"); |     jmethodID constructor = env->GetMethodID(contactsClass, "<init>", "(J)V"); | ||||||
|     jobject newConfig = env->NewObject(contactsClass, constructor, reinterpret_cast<jlong>(user_groups)); |     jobject newConfig = env->NewObject(contactsClass, constructor, reinterpret_cast<jlong>(user_groups)); | ||||||
|  |  | ||||||
|     user_groups->get_or_construct_legacy_group() |  | ||||||
|  |  | ||||||
|     return newConfig; |     return newConfig; | ||||||
| } | } | ||||||
| #pragma clang diagnostic pop | #pragma clang diagnostic pop | ||||||
| @@ -50,7 +48,21 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getCommunityInfo(J | |||||||
|                                                                                jobject thiz, |                                                                                jobject thiz, | ||||||
|                                                                                jstring base_url, |                                                                                jstring base_url, | ||||||
|                                                                                jstring room) { |                                                                                jstring room) { | ||||||
|  |     auto conf = ptrToUserGroups(env, thiz); | ||||||
|  |     auto base_url_bytes = env->GetStringUTFChars(base_url, nullptr); | ||||||
|  |     auto room_bytes = env->GetStringUTFChars(room, nullptr); | ||||||
|  |  | ||||||
|  |     auto community = conf->get_community(base_url_bytes, room_bytes); | ||||||
|  |  | ||||||
|  |     jobject community_info = nullptr; | ||||||
|  |  | ||||||
|  |     if (community) { | ||||||
|  |         serialize_legacy_group_info() | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // TODO: implement getCommunityInfo() |     // TODO: implement getCommunityInfo() | ||||||
|  |     env->ReleaseStringUTFChars(base_url, base_url_bytes); | ||||||
|  |     env->ReleaseStringUTFChars(room, room_bytes); | ||||||
| } | } | ||||||
|  |  | ||||||
| extern "C" | extern "C" | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
|  |  | ||||||
| #include "jni.h" | #include "jni.h" | ||||||
| #include "util.h" | #include "util.h" | ||||||
|  | #include "conversation.h" | ||||||
| #include "session/config/user_groups.hpp" | #include "session/config/user_groups.hpp" | ||||||
|  |  | ||||||
| inline session::config::UserGroups* ptrToUserGroups(JNIEnv *env, jobject obj) { | inline session::config::UserGroups* ptrToUserGroups(JNIEnv *env, jobject obj) { | ||||||
| @@ -51,4 +52,11 @@ inline jobject serialize_members(JNIEnv *env, std::map<std::string, bool> member | |||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | inline jobject serialize_community_info(JNIEnv *env, session::config::community_info info) { | ||||||
|  |     auto priority = info.priority; | ||||||
|  |     auto open_group = session::config::community::parse_full_url(info.full_url()); | ||||||
|  |     auto serialized_community = serialize_open_group(env, (session::config::community) info); | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
| #endif //SESSION_ANDROID_USER_GROUPS_H | #endif //SESSION_ANDROID_USER_GROUPS_H | ||||||
|   | |||||||
| @@ -34,8 +34,7 @@ sealed class ConfigBase(protected val /* yucky */ pointer: Long) { | |||||||
|     external fun encryptionDomain(): String |     external fun encryptionDomain(): String | ||||||
|     external fun confirmPushed(seqNo: Long, newHash: String) |     external fun confirmPushed(seqNo: Long, newHash: String) | ||||||
|     external fun merge(toMerge: Array<Pair<String,ByteArray>>): Int |     external fun merge(toMerge: Array<Pair<String,ByteArray>>): Int | ||||||
|     external fun obsoleteHashes(): List<String> |     external fun currentHashes(): List<String> | ||||||
|     external fun removeObsoleteHashes(toRemove: Array<String>) |  | ||||||
|  |  | ||||||
|     external fun configNamespace(): Int |     external fun configNamespace(): Int | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,5 +7,6 @@ data class Contact( | |||||||
|     var approved: Boolean = false, |     var approved: Boolean = false, | ||||||
|     var approvedMe: Boolean = false, |     var approvedMe: Boolean = false, | ||||||
|     var blocked: Boolean = false, |     var blocked: Boolean = false, | ||||||
|     var profilePicture: UserPic = UserPic.DEFAULT |     var profilePicture: UserPic = UserPic.DEFAULT, | ||||||
|  |     var priority: Int | ||||||
| ) | ) | ||||||
| @@ -57,6 +57,15 @@ data class ConfigurationSyncJob(val destination: Destination): Job { | |||||||
|         // don't run anything if we don't need to push anything |         // don't run anything if we don't need to push anything | ||||||
|         if (configsRequiringPush.isEmpty()) return delegate.handleJobSucceeded(this, dispatcherName) |         if (configsRequiringPush.isEmpty()) return delegate.handleJobSucceeded(this, dispatcherName) | ||||||
|  |  | ||||||
|  |         // need to get the current hashes before we call `push()` | ||||||
|  |         val toDeleteRequest = configsRequiringPush.map { base -> | ||||||
|  |             // accumulate by adding together | ||||||
|  |             base.currentHashes() | ||||||
|  |         }.reduce(List<String>::plus).let { toDeleteFromAllNamespaces -> | ||||||
|  |             if (toDeleteFromAllNamespaces.isEmpty()) null | ||||||
|  |             else SnodeAPI.buildAuthenticatedDeleteBatchInfo(destination.destinationPublicKey(), toDeleteFromAllNamespaces) | ||||||
|  |         } | ||||||
|  |  | ||||||
|         // allow null results here so the list index matches configsRequiringPush |         // allow null results here so the list index matches configsRequiringPush | ||||||
|         val batchObjects: List<Pair<SharedConfigurationMessage, SnodeAPI.SnodeBatchRequestInfo>?> = configsRequiringPush.map { config -> |         val batchObjects: List<Pair<SharedConfigurationMessage, SnodeAPI.SnodeBatchRequestInfo>?> = configsRequiringPush.map { config -> | ||||||
|             val (data, seqNo) = config.push() |             val (data, seqNo) = config.push() | ||||||
| @@ -72,14 +81,6 @@ data class ConfigurationSyncJob(val destination: Destination): Job { | |||||||
|             message to authenticated // to keep track of seqNo for calling confirmPushed later |             message to authenticated // to keep track of seqNo for calling confirmPushed later | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         val toDeleteRequest = configsRequiringPush.map { base -> |  | ||||||
|             base.obsoleteHashes() |  | ||||||
|             // accumulate by adding together |  | ||||||
|         }.reduce(List<String>::plus).let { toDeleteFromAllNamespaces -> |  | ||||||
|             if (toDeleteFromAllNamespaces.isEmpty()) null |  | ||||||
|             else SnodeAPI.buildAuthenticatedDeleteBatchInfo(destination.destinationPublicKey(), toDeleteFromAllNamespaces) |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (batchObjects.any { it == null }) { |         if (batchObjects.any { it == null }) { | ||||||
|             // stop running here, something like a signing error occurred |             // stop running here, something like a signing error occurred | ||||||
|             return delegate.handleJobFailedPermanently(this, dispatcherName, NullPointerException("One or more requests had a null batch request info")) |             return delegate.handleJobFailedPermanently(this, dispatcherName, NullPointerException("One or more requests had a null batch request info")) | ||||||
| @@ -137,8 +138,6 @@ data class ConfigurationSyncJob(val destination: Destination): Job { | |||||||
|                 // confirm pushed seqno |                 // confirm pushed seqno | ||||||
|                 val thisSeqNo = toPushMessage.seqNo |                 val thisSeqNo = toPushMessage.seqNo | ||||||
|                 config.confirmPushed(thisSeqNo, insertHash) |                 config.confirmPushed(thisSeqNo, insertHash) | ||||||
|                 // wipe any of the existing hashes which we deleted (they may or may not be in this namespace) |  | ||||||
|                 config.removeObsoleteHashes(deletedHashes.toTypedArray()) |  | ||||||
|                 Log.d(TAG, "Successfully removed the deleted hashes from ${config.javaClass.simpleName}") |                 Log.d(TAG, "Successfully removed the deleted hashes from ${config.javaClass.simpleName}") | ||||||
|                 // dump and write config after successful |                 // dump and write config after successful | ||||||
|                 if (config.needsDump()) { // usually this will be true? |                 if (config.needsDump()) { // usually this will be true? | ||||||
|   | |||||||
| @@ -137,7 +137,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti | |||||||
|             namespace, |             namespace, | ||||||
|             updateLatestHash = false, |             updateLatestHash = false, | ||||||
|             updateStoredHashes = false, |             updateStoredHashes = false, | ||||||
|         ).filter { (_, hash) -> !forConfigObject.obsoleteHashes().contains(hash) } |         ).filter { (_, hash) -> !forConfigObject.currentHashes().contains(hash) } | ||||||
|  |  | ||||||
|         if (messages.isEmpty()) { |         if (messages.isEmpty()) { | ||||||
|             // no new messages to process |             // no new messages to process | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 0x330a
					0x330a