diff --git a/libsession-util/libsession-util b/libsession-util/libsession-util index e3ccf29db0..c331e2ee19 160000 --- a/libsession-util/libsession-util +++ b/libsession-util/libsession-util @@ -1 +1 @@ -Subproject commit e3ccf29db08aaf0b9bb6bbe72ae5967cd183a78d +Subproject commit c331e2ee191a7acf5360719135d0c5c536d8208f diff --git a/libsession-util/src/main/cpp/CMakeLists.txt b/libsession-util/src/main/cpp/CMakeLists.txt index d01523a24e..47fee4803c 100644 --- a/libsession-util/src/main/cpp/CMakeLists.txt +++ b/libsession-util/src/main/cpp/CMakeLists.txt @@ -61,6 +61,7 @@ target_link_libraries( # Specifies the target library. PUBLIC libsession::config libsession::crypto + libsodium::sodium-internal # Links the target library to the log library # included in the NDK. ${log-lib}) diff --git a/libsession-util/src/main/cpp/config_base.cpp b/libsession-util/src/main/cpp/config_base.cpp index eed3ec56af..1c90b1b81c 100644 --- a/libsession-util/src/main/cpp/config_base.cpp +++ b/libsession-util/src/main/cpp/config_base.cpp @@ -82,7 +82,7 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_confirmPushed(JNIEnv *en #pragma clang diagnostic push #pragma ide diagnostic ignored "bugprone-reserved-identifier" -JNIEXPORT jint JNICALL +JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3Lkotlin_Pair_2(JNIEnv *env, jobject thiz, jobjectArray to_merge) { std::lock_guard lock{util::util_mutex_}; @@ -94,16 +94,20 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3Lkotlin_Pair_2( auto pair = extractHashAndData(env, jElement); configs.push_back(pair); } - return conf->merge(configs); + auto returned = conf->merge(configs); + auto string_stack = util::build_string_stack(env, returned); + return string_stack; } -JNIEXPORT jint JNICALL +JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_merge__Lkotlin_Pair_2(JNIEnv *env, jobject thiz, jobject to_merge) { std::lock_guard lock{util::util_mutex_}; auto conf = ptrToConfigBase(env, thiz); std::vector> configs = {extractHashAndData(env, to_merge)}; - return conf->merge(configs); + auto returned = conf->merge(configs); + auto string_stack = util::build_string_stack(env, returned); + return string_stack; } #pragma clang diagnostic pop diff --git a/libsession-util/src/main/cpp/util.cpp b/libsession-util/src/main/cpp/util.cpp index 77a7e4aa7e..602580f04a 100644 --- a/libsession-util/src/main/cpp/util.cpp +++ b/libsession-util/src/main/cpp/util.cpp @@ -104,6 +104,17 @@ namespace util { return std::pair(session::config::expiration_mode::none, 0); } + jobject build_string_stack(JNIEnv* env, std::vector to_add) { + jclass stack_class = env->FindClass("java/util/Stack"); + jmethodID constructor = env->GetMethodID(stack_class,"", "()V"); + jmethodID add = env->GetMethodID(stack_class, "push", "(Ljava/lang/Object;)Ljava/lang/Object;"); + jobject our_stack = env->NewObject(stack_class, constructor); + for (std::basic_string_view string: to_add) { + env->CallObjectMethod(our_stack, add, env->NewStringUTF(string.data())); + } + return our_stack; + } + } extern "C" diff --git a/libsession-util/src/main/cpp/util.h b/libsession-util/src/main/cpp/util.h index 9348e8bd7e..0d5189b9c9 100644 --- a/libsession-util/src/main/cpp/util.h +++ b/libsession-util/src/main/cpp/util.h @@ -19,6 +19,7 @@ namespace util { session::config::community deserialize_base_community(JNIEnv *env, jobject base_community); jobject serialize_expiry(JNIEnv *env, const session::config::expiration_mode& mode, const std::chrono::seconds& time_seconds); std::pair deserialize_expiry(JNIEnv *env, jobject expiry_mode); + jobject build_string_stack(JNIEnv* env, std::vector to_add); } #endif \ No newline at end of file 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 7e251bc01e..befd0d6d43 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 @@ -10,6 +10,7 @@ import network.loki.messenger.libsession_util.util.UserPic import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage.Kind import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.Log +import java.util.Stack sealed class ConfigBase(protected val /* yucky */ pointer: Long) { @@ -45,13 +46,13 @@ sealed class ConfigBase(protected val /* yucky */ pointer: Long) { external fun dump(): ByteArray external fun encryptionDomain(): String external fun confirmPushed(seqNo: Long, newHash: String) - external fun merge(toMerge: Array>): Int + external fun merge(toMerge: Array>): Stack external fun currentHashes(): List external fun configNamespace(): Int // Singular merge - external fun merge(toMerge: Pair): Int + external fun merge(toMerge: Pair): Stack external fun free() 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 f0b20436fc..8fbe7eb5f6 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 @@ -152,14 +152,18 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti Log.w("Loki", "shared config message handled in configs wasn't SharedConfigurationMessage but was ${message.javaClass.simpleName}") return@forEach } - forConfigObject.merge(hash!! to message.data) - latestMessageTimestamp = if ((message.sentTimestamp ?: 0L) > (latestMessageTimestamp ?: 0L)) { message.sentTimestamp } else { latestMessageTimestamp } + val merged = forConfigObject.merge(hash!! to message.data).firstOrNull { it == hash } + if (merged != null) { + // We successfully merged the hash, we can now update the timestamp + latestMessageTimestamp = if ((message.sentTimestamp ?: 0L) > (latestMessageTimestamp ?: 0L)) { message.sentTimestamp } else { latestMessageTimestamp } + } } catch (e: Exception) { Log.e("Loki", e) } } // process new results - if (forConfigObject.needsDump()) { + // latestMessageTimestamp should always be non-null if the config object needs dump + if (forConfigObject.needsDump() && latestMessageTimestamp != null) { configFactory.persist(forConfigObject, latestMessageTimestamp ?: SnodeAPI.nowWithOffset) } }