From c351cd6038d5431e4b7c50d04ab94425d1a48aae Mon Sep 17 00:00:00 2001 From: 0x330a <92654767+0x330a@users.noreply.github.com> Date: Mon, 27 Feb 2023 17:31:40 +1100 Subject: [PATCH] feat: start to implement group list info classes and wrappers and refactor to use library based hashes --- .../securesms/dependencies/ConfigFactory.kt | 25 --------- libsession-util/src/main/cpp/config_base.cpp | 14 ++++- libsession-util/src/main/cpp/user_groups.cpp | 54 +++++++++++++++++++ libsession-util/src/main/cpp/user_groups.h | 40 ++++++++++++++ .../loki/messenger/libsession_util/Config.kt | 9 +++- .../libsession_util/util/GroupInfo.kt | 22 ++++++++ .../messaging/jobs/ConfigurationSyncJob.kt | 8 ++- .../sending_receiving/pollers/Poller.kt | 5 +- .../utilities/ConfigFactoryProtocol.kt | 3 -- 9 files changed, 142 insertions(+), 38 deletions(-) create mode 100644 libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupInfo.kt 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 6d4bfd57d6..1cf146f557 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ConfigFactory.kt @@ -121,29 +121,4 @@ class ConfigFactory(private val context: Context, } } - override fun appendHash(configObject: ConfigBase, hash: String) { - when (configObject) { - is UserProfile -> userHashes.add(hash) - is Contacts -> contactsHashes.add(hash) - is ConversationVolatileConfig -> convoHashes.add(hash) - else -> throw UnsupportedOperationException("Can't support type of ${configObject::class.simpleName} yet") - } - } - - override fun getHashesFor(forConfigObject: ConfigBase): List = - when (forConfigObject) { - is UserProfile -> userHashes.toList() - is Contacts -> contactsHashes.toList() - is ConversationVolatileConfig -> convoHashes.toList() - else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet") - } - - override fun removeHashesFor(forConfigObject: ConfigBase, deletedHashes: Set) = - when (forConfigObject) { - is UserProfile -> userHashes.removeAll(deletedHashes) - is Contacts -> contactsHashes.removeAll(deletedHashes) - is ConversationVolatileConfig -> convoHashes.removeAll(deletedHashes) - else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet") - } - } \ No newline at end of file diff --git a/libsession-util/src/main/cpp/config_base.cpp b/libsession-util/src/main/cpp/config_base.cpp index 7416767537..fdc994246d 100644 --- a/libsession-util/src/main/cpp/config_base.cpp +++ b/libsession-util/src/main/cpp/config_base.cpp @@ -130,7 +130,19 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_removeObsoleteHashes(JNI for (int i = 0; i < number; i++) { auto jElement = (jstring) env->GetObjectArrayElement(to_remove, i); auto element_as_string = env->GetStringUTFChars(jElement, nullptr); - conf->confirm_removed(element_as_string); + // TODO: uncomment when this is re-implemented +// conf->confirm_removed(element_as_string); env->ReleaseStringUTFChars(jElement, element_as_string); } +} +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_obsoleteHashes(JNIEnv *env, jobject thiz) { + auto conf = ptrToConfigBase(env, thiz); + jclass stack = env->FindClass("java/util/Stack"); + jmethodID init = env->GetMethodID(stack, "", "()V"); + jobject our_stack = env->NewObject(stack, init); + jmethodID push = env->GetMethodID(stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;"); + // TODO: implement obsoleteHashes() + return our_stack; } \ No newline at end of file diff --git a/libsession-util/src/main/cpp/user_groups.cpp b/libsession-util/src/main/cpp/user_groups.cpp index f44cfbeec8..ed946cb481 100644 --- a/libsession-util/src/main/cpp/user_groups.cpp +++ b/libsession-util/src/main/cpp/user_groups.cpp @@ -31,6 +31,60 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_00024Companion_new jmethodID constructor = env->GetMethodID(contactsClass, "", "(J)V"); jobject newConfig = env->NewObject(contactsClass, constructor, reinterpret_cast(user_groups)); + user_groups->get_or_construct_legacy_group() + return newConfig; } #pragma clang diagnostic pop + +extern "C" +JNIEXPORT jint JNICALL +Java_network_loki_messenger_libsession_1util_util_GroupInfo_00024LegacyGroupInfo_00024Companion_NAME_1MAX_1LENGTH( + JNIEnv *env, jobject thiz) { + return session::config::legacy_group_info::NAME_MAX_LENGTH; +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getCommunityInfo(JNIEnv *env, + jobject thiz, + jstring base_url, + jstring room) { + // TODO: implement getCommunityInfo() +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getLegacyGroupInfo(JNIEnv *env, + jobject thiz, + jstring session_id) { + // TODO: implement getLegacyGroupInfo() +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getOrConstructCommunityInfo( + JNIEnv *env, jobject thiz, jstring base_url, jstring room, jstring pub_key_hex) { + // TODO: implement getOrConstructCommunityInfo() +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getOrConstructLegacyGroupInfo( + JNIEnv *env, jobject thiz, jstring session_id) { + // TODO: implement getOrConstructLegacyGroupInfo() +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_UserGroupsConfig_set__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_CommunityInfo_2( + JNIEnv *env, jobject thiz, jobject community_info) { + // TODO: implement set() +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_UserGroupsConfig_set__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_LegacyGroupInfo_2( + JNIEnv *env, jobject thiz, jobject legacy_group_info) { + // TODO: implement set() +} \ No newline at end of file diff --git a/libsession-util/src/main/cpp/user_groups.h b/libsession-util/src/main/cpp/user_groups.h index bd4a46e260..efc928a427 100644 --- a/libsession-util/src/main/cpp/user_groups.h +++ b/libsession-util/src/main/cpp/user_groups.h @@ -11,4 +11,44 @@ inline session::config::UserGroups* ptrToUserGroups(JNIEnv *env, jobject obj) { return (session::config::UserGroups*) env->GetLongField(obj, pointerField); } +/** +val sessionId: String, +val name: String, +val members: Map, +val hidden: Boolean, +val encPubKey: String, +val encSecKey: String, +val priority: Int + */ +inline session::config::legacy_group_info deserialize_legacy_group_info(JNIEnv *env, jobject info) { + auto clazz = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$LegacyGroupInfo"); + auto id_field = env->GetFieldID(clazz, "sessionId", "Ljava/lang/String;"); + auto name_field = env->GetFieldID(clazz, "name", "Ljava/lang/String;"); + auto members_field = env->GetFieldID(clazz, "members", "Ljava/util/Map;"); + auto hidden_field = env->GetFieldID(clazz, "hidden", "Z"); + auto enc_pub_key_field = env->GetFieldID(clazz, "encPubKey", "Ljava/lang/String;"); + auto enc_sec_key_field = env->GetFieldID(clazz, "encSecKey", "Ljava/lang/String;"); + auto priority_field = env->GetFieldID(clazz, "priority", "I"); + jstring id = static_cast(env->GetObjectField(info, id_field)); + jstring name = static_cast(env->GetObjectField(info, name_field)); + jobject members_map = env->GetObjectField(info, members_field); + bool hidden = env->GetBooleanField(info, hidden_field); + jstring enc_pub_key = static_cast(env->GetObjectField(info, enc_pub_key_field)); + jstring enc_sec_key = static_cast(env->GetObjectField(info, enc_sec_key_field)); + int priority = env->GetIntField(info, priority_field); + +} + +inline std::map deserialize_members(JNIEnv *env, jobject members_map) { + +} + +inline jobject serialize_legacy_group_info(JNIEnv *env, session::config::legacy_group_info info) { + return nullptr; +} + +inline jobject serialize_members(JNIEnv *env, std::map members_map) { + return nullptr; +} + #endif //SESSION_ANDROID_USER_GROUPS_H diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt index b91aacd9dd..19e6c64189 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt @@ -3,6 +3,7 @@ package network.loki.messenger.libsession_util import network.loki.messenger.libsession_util.util.ConfigWithSeqNo import network.loki.messenger.libsession_util.util.Contact import network.loki.messenger.libsession_util.util.Conversation +import network.loki.messenger.libsession_util.util.GroupInfo import network.loki.messenger.libsession_util.util.UserPic import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage.Kind @@ -33,6 +34,7 @@ sealed class ConfigBase(protected val /* yucky */ pointer: Long) { external fun encryptionDomain(): String external fun confirmPushed(seqNo: Long, newHash: String) external fun merge(toMerge: Array>): Int + external fun obsoleteHashes(): List external fun removeObsoleteHashes(toRemove: Array) external fun configNamespace(): Int @@ -153,6 +155,11 @@ class UserGroupsConfig(pointer: Long): ConfigBase(pointer) { external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): UserGroupsConfig } - + external fun getCommunityInfo(baseUrl: String, room: String): GroupInfo.CommunityInfo? + external fun getLegacyGroupInfo(sessionId: String): GroupInfo.LegacyGroupInfo? + external fun getOrConstructCommunityInfo(baseUrl: String, room: String, pubKeyHex: String): GroupInfo.CommunityInfo + external fun getOrConstructLegacyGroupInfo(sessionId: String): GroupInfo.LegacyGroupInfo + external fun set(communityInfo: GroupInfo.CommunityInfo) + external fun set(legacyGroupInfo: GroupInfo.LegacyGroupInfo) } \ No newline at end of file diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupInfo.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupInfo.kt new file mode 100644 index 0000000000..23b2618b00 --- /dev/null +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupInfo.kt @@ -0,0 +1,22 @@ +package network.loki.messenger.libsession_util.util + +sealed class GroupInfo { + + data class CommunityInfo(val community: Conversation.Community, val priority: Int) : GroupInfo() + + data class LegacyGroupInfo( + val sessionId: String, + val name: String, + val members: Map, + val hidden: Boolean, + val encPubKey: String, + val encSecKey: String, + val priority: Int + ): GroupInfo() { + companion object { + @Suppress("FunctionName") + external fun NAME_MAX_LENGTH(): Int + } + } + +} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/ConfigurationSyncJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/ConfigurationSyncJob.kt index 6571da0a2d..7d693e9816 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/ConfigurationSyncJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/ConfigurationSyncJob.kt @@ -73,7 +73,7 @@ data class ConfigurationSyncJob(val destination: Destination): Job { } val toDeleteRequest = configsRequiringPush.map { base -> - configFactory.getHashesFor(base) + base.obsoleteHashes() // accumulate by adding together }.reduce(List::plus).let { toDeleteFromAllNamespaces -> if (toDeleteFromAllNamespaces.isEmpty()) null @@ -137,11 +137,9 @@ data class ConfigurationSyncJob(val destination: Destination): Job { // confirm pushed seqno val thisSeqNo = toPushMessage.seqNo config.confirmPushed(thisSeqNo, insertHash) - config. // wipe any of the existing hashes which we deleted (they may or may not be in this namespace) - if (configFactory.removeHashesFor(config, deletedHashes.toSet())) { - Log.d(TAG, "Successfully removed the deleted hashes from ${config.javaClass.simpleName}") - } + config.removeObsoleteHashes(deletedHashes.toTypedArray()) + Log.d(TAG, "Successfully removed the deleted hashes from ${config.javaClass.simpleName}") // dump and write config after successful if (config.needsDump()) { // usually this will be true? configFactory.persist(config) 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 acc58eefba..9a93cf3285 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 @@ -137,7 +137,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti namespace, updateLatestHash = false, updateStoredHashes = false, - ).filter { (_, hash) -> !configFactory.getHashesFor(forConfigObject).contains(hash) } + ).filter { (_, hash) -> !forConfigObject.obsoleteHashes().contains(hash) } if (messages.isEmpty()) { // no new messages to process @@ -153,8 +153,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti return@forEach } Log.d("Loki-DBG", "Merging config of kind ${message.kind} into ${forConfigObject.javaClass.simpleName}") - forConfigObject.merge(message.data) - configFactory.appendHash(forConfigObject, hash!!) + forConfigObject.merge(hash!! to message.data) } catch (e: Exception) { Log.e("Loki", e) } 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 8cdb2b34ee..0997e88a79 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/ConfigFactoryProtocol.kt @@ -10,9 +10,6 @@ interface ConfigFactoryProtocol { val contacts: Contacts? val convoVolatile: ConversationVolatileConfig? fun persist(forConfigObject: ConfigBase) - fun appendHash(configObject: ConfigBase, hash: String) - fun getHashesFor(forConfigObject: ConfigBase): List - fun removeHashesFor(config: ConfigBase, deletedHashes: Set): Boolean } interface ConfigFactoryUpdateListener {