From 3fe22504696ee12f1aa0d19a162ed36342a5cd0f Mon Sep 17 00:00:00 2001 From: 0x330a <92654767+0x330a@users.noreply.github.com> Date: Fri, 1 Sep 2023 13:36:41 +1000 Subject: [PATCH] feat: finish user group wrappers and start volatile convo --- .../conversation/v2/ConversationActivityV2.kt | 4 +-- .../conversation/v2/ConversationViewModel.kt | 5 ++-- .../menus/ConversationActionModeCallback.kt | 4 +-- .../database/SessionContactDatabase.kt | 3 +- .../libsession_util/InstrumentedTests.kt | 14 ++++++++- libsession-util/src/main/cpp/conversation.cpp | 30 +++++++++++++++++++ libsession-util/src/main/cpp/conversation.h | 9 ++++++ libsession-util/src/main/cpp/user_groups.cpp | 9 ++++-- libsession-util/src/main/cpp/user_groups.h | 1 - libsession-util/src/main/cpp/util.h | 7 +++++ .../loki/messenger/libsession_util/Config.kt | 6 +++- .../libsession_util/util/Conversation.kt | 6 ++++ 12 files changed, 84 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 753268b5d9..40c8120347 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -84,7 +84,6 @@ import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel -import org.session.libsession.messaging.utilities.SessionId import org.session.libsession.snode.SnodeAPI import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address.Companion.fromSerialized @@ -99,6 +98,7 @@ import org.session.libsignal.crypto.MnemonicCodec import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.ListenableFuture import org.session.libsignal.utilities.Log +import org.session.libsignal.utilities.SessionId import org.session.libsignal.utilities.guava.Optional import org.session.libsignal.utilities.hexEncodedPrivateKey import org.thoughtcrime.securesms.ApplicationContext @@ -247,7 +247,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val sessionId = SessionId(it.serialize()) val openGroup = lokiThreadDb.getOpenGroupChat(intent.getLongExtra(FROM_GROUP_THREAD_ID, -1)) val address = if (sessionId.prefix == IdPrefix.BLINDED && openGroup != null) { - storage.getOrCreateBlindedIdMapping(sessionId.hexString, openGroup.server, openGroup.publicKey).sessionId?.let { + storage.getOrCreateBlindedIdMapping(sessionId.hexString(), openGroup.server, openGroup.publicKey).sessionId?.let { fromSerialized(it) } ?: GroupUtil.getEncodedOpenGroupInboxID(openGroup, sessionId) } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index 85c9b02c26..118f4856b0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -15,12 +15,11 @@ import kotlinx.coroutines.launch import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.open_groups.OpenGroupApi -import org.session.libsession.messaging.utilities.SessionId import org.session.libsession.messaging.utilities.SodiumUtilities import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.database.Storage +import org.session.libsignal.utilities.SessionId import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.repository.ConversationRepository import java.util.UUID @@ -65,7 +64,7 @@ class ConversationViewModel( val blindedPublicKey: String? get() = if (openGroup == null || edKeyPair == null || !serverCapabilities.contains(OpenGroupApi.Capability.BLIND.name.lowercase())) null else { SodiumUtilities.blindedKeyPair(openGroup!!.publicKey, edKeyPair)?.publicKey?.asBytes - ?.let { SessionId(IdPrefix.BLINDED, it) }?.hexString + ?.let { SessionId(IdPrefix.BLINDED, it) }?.hexString() } val isMessageRequestThread : Boolean diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt index 3746aa52e4..7c94a6230d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt @@ -6,10 +6,10 @@ import android.view.Menu import android.view.MenuItem import network.loki.messenger.R import org.session.libsession.messaging.MessagingModuleConfiguration -import org.session.libsession.messaging.utilities.SessionId import org.session.libsession.messaging.utilities.SodiumUtilities import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.utilities.IdPrefix +import org.session.libsignal.utilities.SessionId import org.thoughtcrime.securesms.conversation.v2.ConversationAdapter import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord @@ -39,7 +39,7 @@ class ConversationActionModeCallback(private val adapter: ConversationAdapter, p val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! val edKeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair()!! val blindedPublicKey = openGroup?.publicKey?.let { SodiumUtilities.blindedKeyPair(it, edKeyPair)?.publicKey?.asBytes } - ?.let { SessionId(IdPrefix.BLINDED, it) }?.hexString + ?.let { SessionId(IdPrefix.BLINDED, it) }?.hexString() fun userCanDeleteSelectedItems(): Boolean { val allSentByCurrentUser = selectedItems.all { it.isOutgoing } val allReceivedByCurrentUser = selectedItems.all { !it.isOutgoing } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SessionContactDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SessionContactDatabase.kt index 51365bb043..1e985d1413 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SessionContactDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SessionContactDatabase.kt @@ -3,11 +3,10 @@ package org.thoughtcrime.securesms.database import android.content.ContentValues import android.content.Context import android.database.Cursor -import androidx.core.database.getStringOrNull import org.session.libsession.messaging.contacts.Contact -import org.session.libsession.messaging.utilities.SessionId import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.IdPrefix +import org.session.libsignal.utilities.SessionId import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper class SessionContactDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) { diff --git a/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt b/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt index 1b883bdc9f..905c28e039 100644 --- a/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt +++ b/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt @@ -12,7 +12,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.session.libsignal.utilities.Hex import org.session.libsignal.utilities.Log -import org.session.libsignal.utilities.toHexString /** * Instrumented test, which will execute on an Android device. @@ -655,4 +654,17 @@ class InstrumentedTests { assertThat(keys.pendingKey(), notNullValue()) } + @Test + fun testGroupMembership() { + val (userPublic, userSecret) = keyPair + val userCurve = Sodium.ed25519PkToCurve25519(userPublic) + val groupConfig = UserGroupsConfig.newInstance(userSecret) + val group = groupConfig.createGroup() + val groupSecret = group.adminKey + val groupPublic = Hex.fromStringCondensed(group.groupSessionId.publicKey) + groupConfig.set(group) + val allClosedGroups = groupConfig.all() + assertThat(allClosedGroups, equalTo(1)) + } + } \ No newline at end of file diff --git a/libsession-util/src/main/cpp/conversation.cpp b/libsession-util/src/main/cpp/conversation.cpp index 4f0f531dea..e43df280d7 100644 --- a/libsession-util/src/main/cpp/conversation.cpp +++ b/libsession-util/src/main/cpp/conversation.cpp @@ -349,4 +349,34 @@ Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_allLegac for (auto contact = convos->begin_legacy_groups(); contact != convos->end(); ++contact) env->CallObjectMethod(our_stack, push, serialize_legacy_group(env, *contact)); return our_stack; +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getClosedGroup(JNIEnv *env, + jobject thiz, + jstring session_id) { + auto config = ptrToConvoInfo(env, thiz); + auto session_id_bytes = env->GetStringUTFChars(session_id, nullptr); + auto group = config->get_group(session_id_bytes); + env->ReleaseStringUTFChars(session_id, session_id_bytes); + if (group) { + auto serialized = serialize_closed_group(env, *group); + return serialized; + } + return nullptr; +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructClosedGroup( + JNIEnv *env, jobject thiz, jstring session_id) { + // TODO: implement getOrConstructClosedGroup() +} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseClosedGroup( + JNIEnv *env, jobject thiz, jstring session_id) { + // TODO: implement eraseClosedGroup() } \ No newline at end of file diff --git a/libsession-util/src/main/cpp/conversation.h b/libsession-util/src/main/cpp/conversation.h index 45e453a595..17288d96eb 100644 --- a/libsession-util/src/main/cpp/conversation.h +++ b/libsession-util/src/main/cpp/conversation.h @@ -42,6 +42,15 @@ inline jobject serialize_legacy_group(JNIEnv *env, session::config::convo::legac return serialized; } +inline jobject serialize_closed_group(JNIEnv* env, session::config::convo::group group) { + jclass clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$ClosedGroup"); + jmethodID constructor = env->GetMethodID(clazz, "", "(Ljava/lang/String;JZ)V"); + auto session_id = env->NewStringUTF(group.id.data()); + auto last_read = group.last_read; + auto unread = group.unread; + return env->NewObject(clazz, constructor, session_id, last_read, unread); +} + inline jobject serialize_any(JNIEnv *env, session::config::convo::any any) { if (auto* dm = std::get_if(&any)) { return serialize_one_to_one(env, *dm); diff --git a/libsession-util/src/main/cpp/user_groups.cpp b/libsession-util/src/main/cpp/user_groups.cpp index 64854c794a..c0de2746f5 100644 --- a/libsession-util/src/main/cpp/user_groups.cpp +++ b/libsession-util/src/main/cpp/user_groups.cpp @@ -203,6 +203,7 @@ inline jobject iterator_as_java_stack(JNIEnv *env, const session::config::UserGr } else if (auto* community = std::get_if(&item)) { serialized = serialize_community_info(env, *community); } else if (auto* closed = std::get_if(&item)) { + LOGD("Item is closed group"); serialized = serialize_closed_group_info(env, *closed); } if (serialized != nullptr) { @@ -218,6 +219,8 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_all(JNIEnv *env, jobject thiz) { std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); + bool isFin = conf->begin().done(); + LOGD("Group iterator has more: %d", isFin); jobject all_stack = iterator_as_java_stack(env, conf->begin(), conf->end()); return all_stack; } @@ -325,7 +328,9 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_allClosedGroupInfo jobject thiz) { std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - return nullptr; + auto closed_group_stack = iterator_as_java_stack(env, conf->begin_groups(), conf->end()); + + return closed_group_stack; } extern "C" @@ -341,7 +346,7 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_createGroup(JNIEnv extern "C" JNIEXPORT jlong JNICALL -Java_network_loki_messenger_libsession_1util_UserGroupsConfig_sizeClosedGroup(JNIEnv *env, + Java_network_loki_messenger_libsession_1util_UserGroupsConfig_sizeClosedGroup(JNIEnv *env, jobject thiz) { std::lock_guard guard{util::util_mutex_}; auto config = ptrToUserGroups(env, thiz); diff --git a/libsession-util/src/main/cpp/user_groups.h b/libsession-util/src/main/cpp/user_groups.h index 5702a41a33..7cd5b4eb3e 100644 --- a/libsession-util/src/main/cpp/user_groups.h +++ b/libsession-util/src/main/cpp/user_groups.h @@ -6,7 +6,6 @@ #include "util.h" #include "conversation.h" #include "session/config/user_groups.hpp" -#include inline session::config::UserGroups* ptrToUserGroups(JNIEnv *env, jobject obj) { jclass configClass = env->FindClass("network/loki/messenger/libsession_util/UserGroupsConfig"); diff --git a/libsession-util/src/main/cpp/util.h b/libsession-util/src/main/cpp/util.h index b77d398a69..c177ae86a0 100644 --- a/libsession-util/src/main/cpp/util.h +++ b/libsession-util/src/main/cpp/util.h @@ -11,6 +11,13 @@ #include "session/config/profile_pic.hpp" #include "session/config/user_groups.hpp" #include "session/config/expiring.hpp" +#include + +#define LOG_TAG "libsession-jni" +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) namespace util { extern std::mutex util_mutex_; 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 be2089bf24..daef7aacd7 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 @@ -158,8 +158,12 @@ class ConversationVolatileConfig(pointer: Long): ConfigBase(pointer) { external fun getLegacyClosedGroup(groupId: String): Conversation.LegacyGroup? external fun getOrConstructLegacyGroup(groupId: String): Conversation.LegacyGroup external fun eraseLegacyClosedGroup(groupId: String): Boolean - external fun erase(conversation: Conversation): Boolean + external fun getClosedGroup(sessionId: String): Conversation.ClosedGroup? + external fun getOrConstructClosedGroup(sessionId: String): Conversation.ClosedGroup + external fun eraseClosedGroup(sessionId: String): Boolean + + external fun erase(conversation: Conversation): Boolean external fun set(toStore: Conversation) /** diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt index 97930e8b40..1ee7802bfe 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt @@ -22,4 +22,10 @@ sealed class Conversation { override var lastRead: Long, override var unread: Boolean ): Conversation() + + data class ClosedGroup( + val sessionId: String, + override var lastRead: Long, + override var unread: Boolean + ): Conversation() } \ No newline at end of file