diff --git a/.drone.yml b/.drone.yml index 0ace6eb..5207f49 100644 --- a/.drone.yml +++ b/.drone.yml @@ -16,8 +16,6 @@ steps: environment: ANDROID_HOME: /usr/lib/android-sdk commands: - - apt-get -y update && apt-get -y install ninja-build - - update-java-alternatives -s java-1.17.0-openjdk-amd64 - env VERSION=`git describe --tags --dirty` ./gradlew publish - name: upload the artifact diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d47521d..4aa7899 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -agp = "8.10.1" -kotlin = "2.1.10" +agp = "8.11.1" +kotlin = "2.2.0" [libraries] diff --git a/library/src/main/cpp/blinded_key.cpp b/library/src/main/cpp/blinded_key.cpp index fac15d1..0dcd875 100644 --- a/library/src/main/cpp/blinded_key.cpp +++ b/library/src/main/cpp/blinded_key.cpp @@ -46,14 +46,11 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blindVersionSignRe jstring path, jbyteArray body) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - auto methodC = util::string_from_jstring(env, method); - auto pathC = util::string_from_jstring(env, path); - auto bytes = session::blind_version_sign_request( jni_utils::JavaByteArrayRef(env, ed25519_secret_key).get(), timestamp, - methodC, - pathC, + jni_utils::JavaStringRef(env, method).view(), + jni_utils::JavaStringRef(env, path).view(), body ? std::make_optional(jni_utils::JavaByteArrayRef(env, body).get()) : std::nullopt ); return util::bytes_from_vector(env, bytes); diff --git a/library/src/main/cpp/config_base.cpp b/library/src/main/cpp/config_base.cpp index 619de96..ae23c72 100644 --- a/library/src/main/cpp/config_base.cpp +++ b/library/src/main/cpp/config_base.cpp @@ -5,21 +5,18 @@ extern "C" { JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_dirty(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto* configBase = ptrToConfigBase(env, thiz); return configBase->is_dirty(); } JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_needsPush(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToConfigBase(env, thiz); return config->needs_push(); } JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_needsDump(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToConfigBase(env, thiz); return config->needs_dump(); } @@ -27,7 +24,6 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_needsDump(JNIEnv *env, j JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_push(JNIEnv *env, jobject thiz) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToConfigBase(env, thiz); auto [seq_no, to_push, to_delete] = config->push(); @@ -51,7 +47,6 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_free(JNIEnv *env, jobjec JNIEXPORT jbyteArray JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_dump(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToConfigBase(env, thiz); auto dumped = config->dump(); jbyteArray bytes = util::bytes_from_vector(env, dumped); @@ -69,16 +64,13 @@ JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_confirmPushed(JNIEnv *env, jobject thiz, jlong seq_no, jobjectArray hash_list) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToConfigBase(env, thiz); auto hash_list_size = env->GetArrayLength(hash_list); std::unordered_set hashes(hash_list_size); for (int i = 0; i < hash_list_size; i++) { - auto hash_jstring = jni_utils::JavaLocalRef(env, (jstring) env->GetObjectArrayElement(hash_list, i)); - auto hash = env->GetStringUTFChars(hash_jstring.get(), nullptr); - hashes.insert(hash); - env->ReleaseStringUTFChars(hash_jstring.get(), hash); + jni_utils::JavaLocalRef hash_jstring(env, (jstring) env->GetObjectArrayElement(hash_list, i)); + hashes.insert(jni_utils::JavaStringRef(env, hash_jstring.get()).copy()); } conf->confirm_pushed(seq_no, hashes); @@ -90,7 +82,6 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3Lkotlin_Pair_2(JNIEnv *env, jobject thiz, jobjectArray to_merge) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToConfigBase(env, thiz); size_t number = env->GetArrayLength(to_merge); std::vector>> configs = {}; @@ -137,7 +128,6 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_00024Companion_kindFor(J extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConfigBase_activeHashes(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToConfigBase(env, thiz); return jni_utils::jstring_list_from_collection(env, conf->active_hashes()); } \ No newline at end of file diff --git a/library/src/main/cpp/config_base.h b/library/src/main/cpp/config_base.h index 0ff16c9..5eebd45 100644 --- a/library/src/main/cpp/config_base.h +++ b/library/src/main/cpp/config_base.h @@ -6,6 +6,7 @@ #include "jni_utils.h" #include #include +#include inline session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj) { auto baseClass = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/ConfigBase")); @@ -17,13 +18,13 @@ inline std::pair> extractHashAndData(JNI auto pair = jni_utils::JavaLocalRef(env, env->FindClass("kotlin/Pair")); jfieldID first = env->GetFieldID(pair.get(), "first", "Ljava/lang/Object;"); jfieldID second = env->GetFieldID(pair.get(), "second", "Ljava/lang/Object;"); - auto hash_as_jstring = jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(kotlin_pair, first))); - auto data_as_jbytes = jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(kotlin_pair, second))); - auto hash_as_string = env->GetStringUTFChars(hash_as_jstring.get(), nullptr); - auto data_as_vector = util::vector_from_bytes(env, data_as_jbytes.get()); - auto ret_pair = std::pair>{hash_as_string, data_as_vector}; - env->ReleaseStringUTFChars(hash_as_jstring.get(), hash_as_string); - return ret_pair; + auto hash_as_jstring = jni_utils::JavaLocalRef(env, reinterpret_cast(env->GetObjectField(kotlin_pair, first))); + auto data_as_jbytes = jni_utils::JavaLocalRef(env, reinterpret_cast(env->GetObjectField(kotlin_pair, second))); + + return std::make_pair( + std::string(jni_utils::JavaStringRef(env, hash_as_jstring.get()).view()), + jni_utils::JavaByteArrayRef(env, data_as_jbytes.get()).copy() + ); } inline session::config::ConfigSig* ptrToConfigSig(JNIEnv* env, jobject obj) { diff --git a/library/src/main/cpp/config_common.cpp b/library/src/main/cpp/config_common.cpp index 1da3fb4..83743eb 100644 --- a/library/src/main/cpp/config_common.cpp +++ b/library/src/main/cpp/config_common.cpp @@ -16,24 +16,23 @@ Java_network_loki_messenger_libsession_1util_ConfigKt_createConfigObject( jbyteArray ed25519_secret_key, jbyteArray initial_dump) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - auto config_name = util::string_from_jstring(env, java_config_name); - auto secret_key = util::vector_from_bytes(env, ed25519_secret_key); + jni_utils::JavaStringRef config_name(env, java_config_name); + jni_utils::JavaByteArrayRef secret_key(env, ed25519_secret_key); auto initial = initial_dump ? std::optional(util::vector_from_bytes(env, initial_dump)) : std::nullopt; - std::lock_guard lock{util::util_mutex_}; - if (config_name == "Contacts") { - return reinterpret_cast(new session::config::Contacts(secret_key, initial)); - } else if (config_name == "UserProfile") { - return reinterpret_cast(new session::config::UserProfile(secret_key, initial)); - } else if (config_name == "UserGroups") { - return reinterpret_cast(new session::config::UserGroups(secret_key, initial)); - } else if (config_name == "ConvoInfoVolatile") { - return reinterpret_cast(new session::config::ConvoInfoVolatile(secret_key, initial)); + if (config_name.view() == "Contacts") { + return reinterpret_cast(new session::config::Contacts(secret_key.get(), initial)); + } else if (config_name.view() == "UserProfile") { + return reinterpret_cast(new session::config::UserProfile(secret_key.get(), initial)); + } else if (config_name.view() == "UserGroups") { + return reinterpret_cast(new session::config::UserGroups(secret_key.get(), initial)); + } else if (config_name.view() == "ConvoInfoVolatile") { + return reinterpret_cast(new session::config::ConvoInfoVolatile(secret_key.get(), initial)); } else { - throw std::invalid_argument("Unknown config name: " + config_name); + throw std::invalid_argument("Unknown config name: " + std::string(config_name.view())); } }); } \ No newline at end of file diff --git a/library/src/main/cpp/contacts.cpp b/library/src/main/cpp/contacts.cpp index 0a5d481..f28dc0c 100644 --- a/library/src/main/cpp/contacts.cpp +++ b/library/src/main/cpp/contacts.cpp @@ -2,6 +2,12 @@ #include "util.h" #include "jni_utils.h" +session::config::Contacts *ptrToContacts(JNIEnv *env, jobject obj) { + auto contactsClass = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/Contacts")); + jfieldID pointerField = env->GetFieldID(contactsClass.get(), "pointer", "J"); + return (session::config::Contacts *) env->GetLongField(obj, pointerField); +} + extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_Contacts_get(JNIEnv *env, jobject thiz, @@ -9,11 +15,8 @@ Java_network_loki_messenger_libsession_1util_Contacts_get(JNIEnv *env, jobject t // If an exception is thrown, return nullptr return jni_utils::run_catching_cxx_exception_or( [=]() -> jobject { - std::lock_guard lock{util::util_mutex_}; auto contacts = ptrToContacts(env, thiz); - auto account_id_chars = env->GetStringUTFChars(account_id, nullptr); - auto contact = contacts->get(account_id_chars); - env->ReleaseStringUTFChars(account_id, account_id_chars); + auto contact = contacts->get(jni_utils::JavaStringRef(env, account_id).view()); if (!contact) return nullptr; jobject j_contact = serialize_contact(env, contact.value()); return j_contact; @@ -27,11 +30,8 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_Contacts_getOrConstruct(JNIEnv *env, jobject thiz, jstring account_id) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; auto contacts = ptrToContacts(env, thiz); - auto account_id_chars = env->GetStringUTFChars(account_id, nullptr); - auto contact = contacts->get_or_construct(account_id_chars); - env->ReleaseStringUTFChars(account_id, account_id_chars); + auto contact = contacts->get_or_construct(jni_utils::JavaStringRef(env, account_id).view()); return serialize_contact(env, contact); }); } @@ -41,7 +41,6 @@ JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_Contacts_set(JNIEnv *env, jobject thiz, jobject contact) { jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; auto contacts = ptrToContacts(env, thiz); auto contact_info = deserialize_contact(env, contact, contacts); contacts->set(contact_info); @@ -53,12 +52,8 @@ JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_Contacts_erase(JNIEnv *env, jobject thiz, jstring account_id) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; auto contacts = ptrToContacts(env, thiz); - auto account_id_chars = env->GetStringUTFChars(account_id, nullptr); - - bool result = contacts->erase(account_id_chars); - env->ReleaseStringUTFChars(account_id, account_id_chars); + bool result = contacts->erase(jni_utils::JavaStringRef(env, account_id).view()); return result; }); } @@ -67,8 +62,166 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_Contacts_all(JNIEnv *env, jobject thiz) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; - auto contacts = ptrToContacts(env, thiz); return jni_utils::jlist_from_collection(env, *ptrToContacts(env, thiz), serialize_contact); }); } + +jobject serialize_contact(JNIEnv *env, session::config::contact_info info) { + auto contactClass = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Contact")); + jmethodID constructor = env->GetMethodID(contactClass.get(), "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZLnetwork/loki/messenger/libsession_util/util/UserPic;JJJLnetwork/loki/messenger/libsession_util/util/ExpiryMode;)V"); + jobject returnObj = env->NewObject(contactClass.get(), + constructor, + jni_utils::JavaLocalRef(env, env->NewStringUTF(info.session_id.data())).get(), + jni_utils::JavaLocalRef(env, env->NewStringUTF(info.name.data())).get(), + jni_utils::JavaLocalRef(env, env->NewStringUTF(info.nickname.data())).get(), + (jboolean) info.approved, + (jboolean) info.approved_me, + (jboolean) info.blocked, + jni_utils::JavaLocalRef(env, util::serialize_user_pic(env, info.profile_picture)).get(), + (jlong) info.created, + (jlong) (info.profile_updated.time_since_epoch().count()), + (jlong) info.priority, + util::serialize_expiry(env, info.exp_mode, info.exp_timer)); + return returnObj; +} + +session::config::contact_info deserialize_contact(JNIEnv *env, jobject info, session::config::Contacts *conf) { + jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact"); + + jfieldID getId, getName, getNick, getApproved, getApprovedMe, getBlocked, getUserPic, getPriority, getExpiry, getHidden, profileUpdatedField; + getId = env->GetFieldID(contactClass, "id", "Ljava/lang/String;"); + getName = env->GetFieldID(contactClass, "name", "Ljava/lang/String;"); + getNick = env->GetFieldID(contactClass, "nickname", "Ljava/lang/String;"); + getApproved = env->GetFieldID(contactClass, "approved", "Z"); + getApprovedMe = env->GetFieldID(contactClass, "approvedMe", "Z"); + getBlocked = env->GetFieldID(contactClass, "blocked", "Z"); + getUserPic = env->GetFieldID(contactClass, "profilePicture", + "Lnetwork/loki/messenger/libsession_util/util/UserPic;"); + getPriority = env->GetFieldID(contactClass, "priority", "J"); + getExpiry = env->GetFieldID(contactClass, "expiryMode", "Lnetwork/loki/messenger/libsession_util/util/ExpiryMode;"); + profileUpdatedField = env->GetFieldID(contactClass, "profileUpdatedEpochSeconds", "J"); + + jni_utils::JavaLocalRef account_id(env, static_cast(env->GetObjectField(info, getId))); + jni_utils::JavaLocalRef name(env, static_cast(env->GetObjectField(info, getName))); + jni_utils::JavaLocalRef nickname(env, static_cast(env->GetObjectField(info, getNick))); + jni_utils::JavaLocalRef user_pic(env, env->GetObjectField(info, getUserPic)); + jni_utils::JavaLocalRef expiry_mode(env, env->GetObjectField(info, getExpiry)); + + auto expiry_pair = util::deserialize_expiry(env, expiry_mode.get()); + auto profile_updated_seconds = env->GetLongField(info, profileUpdatedField); + + auto contact_info = conf->get_or_construct(jni_utils::JavaStringRef(env, account_id.get()).view()); + if (name.get()) { + contact_info.name = jni_utils::JavaStringRef(env, name.get()).view(); + } + if (nickname.get()) { + contact_info.nickname = jni_utils::JavaStringRef(env, nickname.get()).view(); + } + contact_info.approved = env->GetBooleanField(info, getApproved); + contact_info.approved_me = env->GetBooleanField(info, getApprovedMe); + contact_info.blocked = env->GetBooleanField(info, getBlocked); + contact_info.profile_updated = std::chrono::sys_seconds{std::chrono::seconds{profile_updated_seconds}}; + if (user_pic.get() != nullptr) { + contact_info.profile_picture = util::deserialize_user_pic(env, user_pic.get()); + } + + contact_info.priority = env->GetLongField(info, getPriority); + contact_info.exp_mode = expiry_pair.first; + contact_info.exp_timer = std::chrono::seconds(expiry_pair.second); + + return contact_info; +} + +jobject serialize_blinded_contact(JNIEnv *env, const session::config::blinded_contact_info &info) { + jni_utils::JavaLocalRef clazz(env, env->FindClass("network/loki/messenger/libsession_util/util/BlindedContact")); + auto constructor = env->GetMethodID(clazz.get(), "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JLnetwork/loki/messenger/libsession_util/util/UserPic;)V"); + + return env->NewObject( + clazz.get(), + constructor, + jni_utils::JavaLocalRef(env, env->NewStringUTF(info.session_id().c_str())).get(), + jni_utils::JavaLocalRef(env, env->NewStringUTF(info.community_base_url().data())).get(), + jni_utils::JavaLocalRef(env, env->NewStringUTF(info.community_pubkey_hex().data())).get(), + jni_utils::JavaLocalRef(env, env->NewStringUTF(info.name.c_str())).get(), + (jlong) (info.created.time_since_epoch().count()), + jni_utils::JavaLocalRef(env, util::serialize_user_pic(env, info.profile_picture)).get() + ); +} + +session::config::blinded_contact_info deserialize_blinded_contact(JNIEnv *env, jobject jInfo) { + jni_utils::JavaLocalRef clazz(env, env->GetObjectClass(jInfo)); + auto idField = env->GetFieldID(clazz.get(), "id", "Ljava/lang/String;"); + auto communityServerField = env->GetFieldID(clazz.get(), "communityServer", "Ljava/lang/String;"); + auto getCommunityServerPubKey = env->GetMethodID(clazz.get(), "getCommunityServerPubKey", "()[B"); + auto nameField = env->GetFieldID(clazz.get(), "name", "Ljava/lang/String;"); + auto createdEpochSecondsField = env->GetFieldID(clazz.get(), "createdEpochSeconds", "J"); + auto profilePicField = env->GetFieldID(clazz.get(), "profilePic", "Lnetwork/loki/messenger/libsession_util/util/UserPic;"); + + session::config::blinded_contact_info info( + jni_utils::JavaStringRef(env, (jstring) env->GetObjectField(jInfo, communityServerField)).view(), + jni_utils::JavaByteArrayRef(env, (jbyteArray) env->CallObjectMethod(jInfo, getCommunityServerPubKey)).get(), + jni_utils::JavaStringRef(env, (jstring) env->GetObjectField(jInfo, idField)).view() + ); + info.created = std::chrono::sys_seconds{std::chrono::seconds{env->GetLongField(jInfo, createdEpochSecondsField)}}; + info.profile_picture = util::deserialize_user_pic(env, jni_utils::JavaLocalRef(env, env->GetObjectField(jInfo, profilePicField)).get()); + + return info; +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_getOrConstructBlinded(JNIEnv *env, + jobject thiz, + jstring community_server_url, + jstring community_server_pub_key_hex, + jstring blinded_id) { + return serialize_blinded_contact(env, ptrToContacts(env, thiz)->get_or_construct_blinded( + jni_utils::JavaStringRef(env, community_server_url).view(), + jni_utils::JavaStringRef(env, community_server_pub_key_hex).view(), + jni_utils::JavaStringRef(env, blinded_id).view() + )); +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_setBlinded(JNIEnv *env, jobject thiz, + jobject contact) { + ptrToContacts(env, thiz)->set_blinded( + deserialize_blinded_contact(env, contact) + ); +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_eraseBlinded(JNIEnv *env, jobject thiz, + jstring community_server_url, + jstring blinded_id) { + ptrToContacts(env, thiz)->erase_blinded( + jni_utils::JavaStringRef(env, community_server_url).view(), + jni_utils::JavaStringRef(env, blinded_id).view() + ); +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_allBlinded(JNIEnv *env, jobject thiz) { + return jni_utils::jlist_from_collection( + env, + ptrToContacts(env, thiz)->blinded(), + serialize_blinded_contact + ); +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_getBlinded(JNIEnv *env, + jobject thiz, + jstring blinded_id) { + auto result = ptrToContacts(env, thiz)->get_blinded(jni_utils::JavaStringRef(env, blinded_id).view()); + + if (result) { + return serialize_blinded_contact(env, *result); + } else { + return nullptr; + } +} \ No newline at end of file diff --git a/library/src/main/cpp/contacts.h b/library/src/main/cpp/contacts.h index 0998227..4122a18 100644 --- a/library/src/main/cpp/contacts.h +++ b/library/src/main/cpp/contacts.h @@ -2,108 +2,11 @@ #define SESSION_ANDROID_CONTACTS_H #include -#include #include "session/config/contacts.hpp" -#include "util.h" -#include "jni_utils.h" -inline session::config::Contacts *ptrToContacts(JNIEnv *env, jobject obj) { - auto contactsClass = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/Contacts")); - jfieldID pointerField = env->GetFieldID(contactsClass.get(), "pointer", "J"); - return (session::config::Contacts *) env->GetLongField(obj, pointerField); -} - -inline jobject serialize_contact(JNIEnv *env, session::config::contact_info info) { - auto contactClass = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Contact")); - jmethodID constructor = env->GetMethodID(contactClass.get(), "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZLnetwork/loki/messenger/libsession_util/util/UserPic;JLnetwork/loki/messenger/libsession_util/util/ExpiryMode;)V"); - auto id = jni_utils::JavaLocalRef(env, env->NewStringUTF(info.session_id.data())); - auto name = jni_utils::JavaLocalRef(env, env->NewStringUTF(info.name.data())); - auto nickname = jni_utils::JavaLocalRef(env, env->NewStringUTF(info.nickname.data())); - jboolean approved, approvedMe, blocked; - approved = info.approved; - approvedMe = info.approved_me; - blocked = info.blocked; - auto created = info.created; - auto profilePic = jni_utils::JavaLocalRef(env, util::serialize_user_pic(env, info.profile_picture)); - jobject returnObj = env->NewObject(contactClass.get(), constructor, id.get(), name.get(), nickname.get(), approved, - approvedMe, blocked, profilePic.get(), (jlong)info.priority, - util::serialize_expiry(env, info.exp_mode, info.exp_timer)); - return returnObj; -} - -inline session::config::contact_info deserialize_contact(JNIEnv *env, jobject info, session::config::Contacts *conf) { - jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact"); - - jfieldID getId, getName, getNick, getApproved, getApprovedMe, getBlocked, getUserPic, getPriority, getExpiry, getHidden; - getId = env->GetFieldID(contactClass, "id", "Ljava/lang/String;"); - getName = env->GetFieldID(contactClass, "name", "Ljava/lang/String;"); - getNick = env->GetFieldID(contactClass, "nickname", "Ljava/lang/String;"); - getApproved = env->GetFieldID(contactClass, "approved", "Z"); - getApprovedMe = env->GetFieldID(contactClass, "approvedMe", "Z"); - getBlocked = env->GetFieldID(contactClass, "blocked", "Z"); - getUserPic = env->GetFieldID(contactClass, "profilePicture", - "Lnetwork/loki/messenger/libsession_util/util/UserPic;"); - getPriority = env->GetFieldID(contactClass, "priority", "J"); - getExpiry = env->GetFieldID(contactClass, "expiryMode", "Lnetwork/loki/messenger/libsession_util/util/ExpiryMode;"); - auto account_id = jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(info, getId))); - auto name = jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(info, getName))); - auto nickname = jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(info, getNick))); - bool approved, approvedMe, blocked, hidden; - int priority = env->GetLongField(info, getPriority); - approved = env->GetBooleanField(info, getApproved); - approvedMe = env->GetBooleanField(info, getApprovedMe); - blocked = env->GetBooleanField(info, getBlocked); - auto user_pic = jni_utils::JavaLocalRef(env, env->GetObjectField(info, getUserPic)); - auto expiry_mode = jni_utils::JavaLocalRef(env, env->GetObjectField(info, getExpiry)); - - auto expiry_pair = util::deserialize_expiry(env, expiry_mode.get()); - - std::string url; - std::vector key; - - if (user_pic.get() != nullptr) { - auto deserialized_pic = util::deserialize_user_pic(env, user_pic.get()); - auto url_jstring = deserialized_pic.first; - auto url_bytes = env->GetStringUTFChars(url_jstring, nullptr); - url = std::string(url_bytes); - env->ReleaseStringUTFChars(url_jstring, url_bytes); - key = util::vector_from_bytes(env, deserialized_pic.second); - } - - auto account_id_bytes = env->GetStringUTFChars(account_id.get(), nullptr); - auto name_bytes = name.get() ? env->GetStringUTFChars(name.get(), nullptr) : nullptr; - auto nickname_bytes = nickname.get() ? env->GetStringUTFChars(nickname.get(), nullptr) : nullptr; - - auto contact_info = conf->get_or_construct(account_id_bytes); - if (name_bytes) { - contact_info.name = name_bytes; - } - if (nickname_bytes) { - contact_info.nickname = nickname_bytes; - } - contact_info.approved = approved; - contact_info.approved_me = approvedMe; - contact_info.blocked = blocked; - if (!url.empty() && !key.empty()) { - contact_info.profile_picture = session::config::profile_pic(url, key); - } else { - contact_info.profile_picture = session::config::profile_pic(); - } - - env->ReleaseStringUTFChars(account_id.get(), account_id_bytes); - if (name_bytes) { - env->ReleaseStringUTFChars(name.get(), name_bytes); - } - if (nickname_bytes) { - env->ReleaseStringUTFChars(nickname.get(), nickname_bytes); - } - - contact_info.priority = priority; - contact_info.exp_mode = expiry_pair.first; - contact_info.exp_timer = std::chrono::seconds(expiry_pair.second); - - return contact_info; -} +session::config::Contacts *ptrToContacts(JNIEnv *env, jobject obj); +jobject serialize_contact(JNIEnv *env, session::config::contact_info info); +session::config::contact_info deserialize_contact(JNIEnv *env, jobject info, session::config::Contacts *conf); #endif //SESSION_ANDROID_CONTACTS_H diff --git a/library/src/main/cpp/conversation.cpp b/library/src/main/cpp/conversation.cpp index f501c04..b18a56f 100644 --- a/library/src/main/cpp/conversation.cpp +++ b/library/src/main/cpp/conversation.cpp @@ -3,11 +3,154 @@ #include "jni_utils.h" + jobject serialize_one_to_one(JNIEnv *env, const session::config::convo::one_to_one &one_to_one) { + jni_utils::JavaLocalRef clazz(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne")); + return env->NewObject(clazz.get(), + env->GetMethodID(clazz.get(), "", "(Ljava/lang/String;JZ)V"), + jni_utils::JavaLocalRef(env, env->NewStringUTF(one_to_one.session_id.data())).get(), + (jlong) one_to_one.last_read, + (jboolean) one_to_one.unread); +} + +session::config::convo::one_to_one deserialize_one_to_one(JNIEnv *env, jobject info) { + jni_utils::JavaLocalRef clazz(env, env->GetObjectClass(info)); + + auto id_getter = env->GetFieldID(clazz.get(), "accountId", "Ljava/lang/String;"); + auto last_read_getter = env->GetFieldID(clazz.get(), "lastRead", "J"); + auto unread_getter = env->GetFieldID(clazz.get(), "unread", "Z"); + + session::config::convo::one_to_one r( + jni_utils::JavaStringRef(env, jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(info, id_getter))).get()).view() + ); + + r.last_read = env->GetLongField(info, last_read_getter); + r.unread = env->GetBooleanField(info, unread_getter); + return r; +} + +jobject serialize_community(JNIEnv *env, const session::config::convo::community& community) { + jni_utils::JavaLocalRef clazz(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$Community")); + return env->NewObject(clazz.get(), + env->GetMethodID(clazz.get(), "", + "(Lnetwork/loki/messenger/libsession_util/util/BaseCommunityInfo;JZ)V"), + jni_utils::JavaLocalRef(env, util::serialize_base_community(env, community)).get(), + (jlong) community.last_read, + (jboolean) community.unread); +} + +session::config::convo::community deserialize_community(JNIEnv *env, jobject info) { + jni_utils::JavaLocalRef clazz(env, env->GetObjectClass(info)); + auto base_community_getter = env->GetFieldID(clazz.get(), "baseCommunityInfo", "Lnetwork/loki/messenger/libsession_util/util/BaseCommunityInfo;"); + auto last_read_getter = env->GetFieldID(clazz.get(), "lastRead", "J"); + auto unread_getter = env->GetFieldID(clazz.get(), "unread", "Z"); + + auto base_community = util::deserialize_base_community(env, jni_utils::JavaLocalRef(env, env->GetObjectField(info, base_community_getter)).get()); + + session::config::convo::community community( + base_community.base_url(), + base_community.room(), + base_community.pubkey() + ); + + community.last_read = env->GetLongField(info, last_read_getter); + community.unread = env->GetBooleanField(info, unread_getter); + + return community; +} + + +jobject serialize_legacy_group(JNIEnv *env, const session::config::convo::legacy_group& group) { + jni_utils::JavaLocalRef clazz(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyGroup")); + return env->NewObject(clazz.get(), + env->GetMethodID(clazz.get(), "","(Ljava/lang/String;JZ)V"), + jni_utils::JavaLocalRef(env, env->NewStringUTF(group.id.data())).get(), + (jlong) group.last_read, + (jboolean) group.unread); +} + +session::config::convo::legacy_group deserialize_legacy_closed_group(JNIEnv *env, jobject info) { + jni_utils::JavaLocalRef clazz(env, env->GetObjectClass(info)); + auto group_id_getter = env->GetFieldID(clazz.get(), "groupId", "Ljava/lang/String;"); + auto last_read_getter = env->GetFieldID(clazz.get(), "lastRead", "J"); + auto unread_getter = env->GetFieldID(clazz.get(), "unread", "Z"); + + session::config::convo::legacy_group lg( + jni_utils::JavaStringRef(env, jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(info, group_id_getter))).get()).view() + ); + + lg.last_read = env->GetLongField(info, last_read_getter); + lg.unread = env->GetBooleanField(info, unread_getter); + return lg; +} + +jobject serialize_closed_group(JNIEnv* env, const session::config::convo::group &group) { + jni_utils::JavaLocalRef clazz(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$ClosedGroup")); + return env->NewObject(clazz.get(), + env->GetMethodID(clazz.get(), "", "(Ljava/lang/String;JZ)V"), + jni_utils::JavaLocalRef(env, env->NewStringUTF(group.id.data())).get(), + (jlong) group.last_read, + (jboolean) group.unread); +} + +session::config::convo::group deserialize_closed_group(JNIEnv* env, jobject info) { + jni_utils::JavaLocalRef clazz(env, env->GetObjectClass(info)); + auto id_getter = env->GetFieldID(clazz.get(), "accountId", "Ljava/lang/String;"); + auto last_read_getter = env->GetFieldID(clazz.get(), "lastRead", "J"); + auto unread_getter = env->GetFieldID(clazz.get(), "unread", "Z"); + + session::config::convo::group g( + jni_utils::JavaStringRef(env, jni_utils::JavaLocalRef(env, (jstring) env->GetObjectField(info, id_getter)).get()).view()); + + g.last_read = env->GetLongField(info, last_read_getter); + g.unread = env->GetBooleanField(info, unread_getter); + + return g; +} + +jobject serialize_blinded_one_to_one(JNIEnv *env, const session::config::convo::blinded_one_to_one &blinded_one_to_one) { + jni_utils::JavaLocalRef clazz(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$BlindedOneToOne")); + return env->NewObject( + clazz.get(), + env->GetMethodID(clazz.get(), "", "(Ljava/lang/String;JZ)V"), + jni_utils::JavaLocalRef(env, env->NewStringUTF(blinded_one_to_one.blinded_session_id.data())).get(), + (jlong) blinded_one_to_one.last_read, + (jboolean) blinded_one_to_one.unread + ); +} + +session::config::convo::blinded_one_to_one deserialize_blinded_one_to_one(JNIEnv *env, jobject info) { + jni_utils::JavaLocalRef clazz(env, env->GetObjectClass(info)); + auto id_field_id = env->GetFieldID(clazz.get(), "blindedAccountId", "Ljava/lang/String;"); + auto last_read_field_id = env->GetFieldID(clazz.get(), "lastRead", "J"); + auto unread_field_id = env->GetFieldID(clazz.get(), "unread", "Z"); + + session::config::convo::blinded_one_to_one r( + jni_utils::JavaStringRef(env, jni_utils::JavaLocalRef(env, (jstring) env->GetObjectField(info, id_field_id)).get()).view(), true); + + r.last_read = env->GetLongField(info, last_read_field_id); + r.unread = env->GetBooleanField(info, unread_field_id); + + return r; +} + +jobject serialize_any(JNIEnv *env, session::config::convo::any any) { + if (auto* dm = std::get_if(&any)) { + return serialize_one_to_one(env, *dm); + } else if (auto* og = std::get_if(&any)) { + return serialize_community(env, *og); + } else if (auto* lgc = std::get_if(&any)) { + return serialize_legacy_group(env, *lgc); + } else if (auto* gc = std::get_if(&any)) { + return serialize_closed_group(env, *gc); + } + return nullptr; +} + + extern "C" JNIEXPORT jint JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_sizeOneToOnes(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto conversations = ptrToConvoInfo(env, thiz); return conversations->size_1to1(); } @@ -17,21 +160,20 @@ JNIEXPORT jint JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseAll(JNIEnv *env, jobject thiz, jobject predicate) { - std::lock_guard lock{util::util_mutex_}; auto conversations = ptrToConvoInfo(env, thiz); - jclass predicate_class = env->FindClass("kotlin/jvm/functions/Function1"); - jmethodID predicate_call = env->GetMethodID(predicate_class, "invoke", "(Ljava/lang/Object;)Ljava/lang/Object;"); + jni_utils::JavaLocalRef predicate_class(env, env->GetObjectClass(predicate)); + jmethodID predicate_call = env->GetMethodID(predicate_class.get(), "invoke", "(Ljava/lang/Object;)Ljava/lang/Object;"); - jclass bool_class = env->FindClass("java/lang/Boolean"); - jmethodID bool_get = env->GetMethodID(bool_class, "booleanValue", "()Z"); + jni_utils::JavaLocalRef bool_class(env, env->FindClass("java/lang/Boolean")); + jmethodID bool_get = env->GetMethodID(bool_class.get(), "booleanValue", "()Z"); int removed = 0; auto to_erase = std::vector(); for (auto it = conversations->begin(); it != conversations->end(); ++it) { - auto result = env->CallObjectMethod(predicate, predicate_call, serialize_any(env, *it)); - bool bool_result = env->CallBooleanMethod(result, bool_get); + jni_utils::JavaLocalRef result(env, env->CallObjectMethod(predicate, predicate_call, jni_utils::JavaLocalRef(env, serialize_any(env, *it)).get())); + bool bool_result = env->CallBooleanMethod(result.get(), bool_get); if (bool_result) { to_erase.push_back(*it); } @@ -50,57 +192,25 @@ extern "C" JNIEXPORT jint JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_size(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToConvoInfo(env, thiz); return (jint)config->size(); } + extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_empty(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToConvoInfo(env, thiz); return config->empty(); } -extern "C" -JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_set(JNIEnv *env, - jobject thiz, - jobject to_store) { - std::lock_guard lock{util::util_mutex_}; - - auto convos = ptrToConvoInfo(env, thiz); - jclass one_to_one = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne"); - jclass open_group = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$Community"); - jclass legacy_closed_group = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyGroup"); - jclass closed_group = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$ClosedGroup"); - - jclass to_store_class = env->GetObjectClass(to_store); - if (env->IsSameObject(to_store_class, one_to_one)) { - // store as 1to1 - convos->set(deserialize_one_to_one(env, to_store, convos)); - } else if (env->IsSameObject(to_store_class,open_group)) { - // store as open_group - convos->set(deserialize_community(env, to_store, convos)); - } else if (env->IsSameObject(to_store_class,legacy_closed_group)) { - // store as legacy_closed_group - convos->set(deserialize_legacy_closed_group(env, to_store, convos)); - } else if (env->IsSameObject(to_store_class, closed_group)) { - // store as new closed group - convos->set(deserialize_closed_group(env, to_store, convos)); - } -} extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOneToOne(JNIEnv *env, jobject thiz, jstring pub_key_hex) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto param = env->GetStringUTFChars(pub_key_hex, nullptr); - auto internal = convos->get_1to1(param); - env->ReleaseStringUTFChars(pub_key_hex, param); + auto internal = convos->get_1to1(jni_utils::JavaStringRef(env, pub_key_hex).view()); if (internal) { return serialize_one_to_one(env, *internal); } @@ -110,38 +220,26 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructOneToOne( JNIEnv *env, jobject thiz, jstring pub_key_hex) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto param = env->GetStringUTFChars(pub_key_hex, nullptr); - auto internal = convos->get_or_construct_1to1(param); - env->ReleaseStringUTFChars(pub_key_hex, param); - return serialize_one_to_one(env, internal); + return serialize_one_to_one(env, convos->get_or_construct_1to1(jni_utils::JavaStringRef(env, pub_key_hex).view())); } extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseOneToOne(JNIEnv *env, jobject thiz, jstring pub_key_hex) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto param = env->GetStringUTFChars(pub_key_hex, nullptr); - auto result = convos->erase_1to1(param); - env->ReleaseStringUTFChars(pub_key_hex, param); - return result; + return convos->erase_1to1(jni_utils::JavaStringRef(env, pub_key_hex).view()); } extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getCommunity__Ljava_lang_String_2Ljava_lang_String_2( JNIEnv *env, jobject thiz, jstring base_url, jstring room) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto base_url_chars = env->GetStringUTFChars(base_url, nullptr); - auto room_chars = env->GetStringUTFChars(room, nullptr); - auto open = convos->get_community(base_url_chars, room_chars); + auto open = convos->get_community(jni_utils::JavaStringRef(env, base_url).view(), jni_utils::JavaStringRef(env, room).view()); if (open) { - auto serialized = serialize_open_group(env, *open); - return serialized; + return serialize_community(env, *open); } return nullptr; } @@ -149,115 +247,82 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructCommunity__Ljava_lang_String_2Ljava_lang_String_2_3B( JNIEnv *env, jobject thiz, jstring base_url, jstring room, jbyteArray pub_key) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto base_url_chars = env->GetStringUTFChars(base_url, nullptr); - auto room_chars = env->GetStringUTFChars(room, nullptr); - auto pub_key_vector = util::vector_from_bytes(env, pub_key); - auto open = convos->get_or_construct_community(base_url_chars, room_chars, pub_key_vector); - auto serialized = serialize_open_group(env, open); - return serialized; + auto community = convos->get_or_construct_community( + jni_utils::JavaStringRef(env, base_url).view(), + jni_utils::JavaStringRef(env, room).view(), + jni_utils::JavaByteArrayRef(env, pub_key).get()); + return serialize_community(env, community); } extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructCommunity__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2( JNIEnv *env, jobject thiz, jstring base_url, jstring room, jstring pub_key_hex) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto base_url_chars = env->GetStringUTFChars(base_url, nullptr); - auto room_chars = env->GetStringUTFChars(room, nullptr); - auto hex_chars = env->GetStringUTFChars(pub_key_hex, nullptr); - auto open = convos->get_or_construct_community(base_url_chars, room_chars, hex_chars); - env->ReleaseStringUTFChars(base_url, base_url_chars); - env->ReleaseStringUTFChars(room, room_chars); - env->ReleaseStringUTFChars(pub_key_hex, hex_chars); - auto serialized = serialize_open_group(env, open); - return serialized; + auto community = convos->get_or_construct_community( + jni_utils::JavaStringRef(env, base_url).view(), + jni_utils::JavaStringRef(env, room).view(), + jni_utils::JavaStringRef(env, pub_key_hex).view()); + return serialize_community(env, community); } extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseCommunity__Lnetwork_loki_messenger_libsession_1util_util_Conversation_Community_2(JNIEnv *env, jobject thiz, jobject open_group) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto deserialized = deserialize_community(env, open_group, convos); + auto deserialized = deserialize_community(env, open_group); return convos->erase(deserialized); } extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseCommunity__Ljava_lang_String_2Ljava_lang_String_2( JNIEnv *env, jobject thiz, jstring base_url, jstring room) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto base_url_chars = env->GetStringUTFChars(base_url, nullptr); - auto room_chars = env->GetStringUTFChars(room, nullptr); - auto result = convos->erase_community(base_url_chars, room_chars); - env->ReleaseStringUTFChars(base_url, base_url_chars); - env->ReleaseStringUTFChars(room, room_chars); - return result; + return convos->erase_community( + jni_utils::JavaStringRef(env, base_url).view(), + jni_utils::JavaStringRef(env, room).view()); } extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getLegacyClosedGroup( JNIEnv *env, jobject thiz, jstring group_id) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto id_chars = env->GetStringUTFChars(group_id, nullptr); - auto lgc = convos->get_legacy_group(id_chars); - env->ReleaseStringUTFChars(group_id, id_chars); + auto lgc = convos->get_legacy_group(jni_utils::JavaStringRef(env, group_id).view()); if (lgc) { - auto serialized = serialize_legacy_group(env, *lgc); - return serialized; + return serialize_legacy_group(env, *lgc); } + return nullptr; } extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructLegacyGroup( JNIEnv *env, jobject thiz, jstring group_id) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto id_chars = env->GetStringUTFChars(group_id, nullptr); - auto lgc = convos->get_or_construct_legacy_group(id_chars); - env->ReleaseStringUTFChars(group_id, id_chars); + auto lgc = convos->get_or_construct_legacy_group(jni_utils::JavaStringRef(env, group_id).view()); return serialize_legacy_group(env, lgc); } extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseLegacyClosedGroup( JNIEnv *env, jobject thiz, jstring group_id) { - std::lock_guard lock{util::util_mutex_}; - auto convos = ptrToConvoInfo(env, thiz); - auto id_chars = env->GetStringUTFChars(group_id, nullptr); - auto result = convos->erase_legacy_group(id_chars); - env->ReleaseStringUTFChars(group_id, id_chars); - return result; -} -extern "C" -JNIEXPORT jboolean JNICALL -Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_erase(JNIEnv *env, - jobject thiz, - jobject conversation) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); - auto deserialized = deserialize_any(env, conversation, convos); - if (!deserialized.has_value()) return false; - return convos->erase(*deserialized); + return convos->erase_legacy_group(jni_utils::JavaStringRef(env, group_id).view()); } + extern "C" JNIEXPORT jint JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_sizeCommunities(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); return convos->size_communities(); } + extern "C" JNIEXPORT jint JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_sizeLegacyClosedGroups( JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); return convos->size_legacy_groups(); } @@ -265,7 +330,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_all(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); return jni_utils::jlist_from_collection(env, *convos, serialize_any); @@ -274,7 +338,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_allOneToOnes(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); return jni_utils::jlist_from_iterator(env, convos->begin_1to1(), convos->end(), serialize_one_to_one); @@ -283,16 +346,14 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_allCommunities(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); return jni_utils::jlist_from_iterator(env, convos->begin_communities(), convos->end(), - serialize_open_group); + serialize_community); } extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_allLegacyClosedGroups( JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); return jni_utils::jlist_from_iterator(env, convos->begin_legacy_groups(), convos->end(), serialize_legacy_group); @@ -302,7 +363,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_allClosedGroups(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto convos = ptrToConvoInfo(env, thiz); return jni_utils::jlist_from_iterator(env, convos->begin_groups(), convos->end(), serialize_closed_group); @@ -314,12 +374,9 @@ Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getClose 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); + auto group = config->get_group(jni_utils::JavaStringRef(env, session_id).view()); if (group) { - auto serialized = serialize_closed_group(env, *group); - return serialized; + return serialize_closed_group(env, *group); } return nullptr; } @@ -329,9 +386,7 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructClosedGroup( 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_or_construct_group(session_id_bytes); - env->ReleaseStringUTFChars(session_id, session_id_bytes); + auto group = config->get_or_construct_group(jni_utils::JavaStringRef(env, session_id).view()); return serialize_closed_group(env, group); } @@ -340,8 +395,54 @@ JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseClosedGroup( JNIEnv *env, jobject thiz, jstring session_id) { auto config = ptrToConvoInfo(env, thiz); - auto session_id_bytes = env->GetStringUTFChars(session_id, nullptr); - auto erased = config->erase_group(session_id_bytes); - env->ReleaseStringUTFChars(session_id, session_id_bytes); - return erased; + return config->erase_group(jni_utils::JavaStringRef(env, session_id).view()); +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_setOneToOne( + JNIEnv *env, jobject thiz, jobject o) { + ptrToConvoInfo(env, thiz)->set(deserialize_one_to_one(env, o)); +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_setCommunity( + JNIEnv *env, jobject thiz, jobject o) { + ptrToConvoInfo(env, thiz)->set(deserialize_community(env, o)); +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_setLegacyGruop( + JNIEnv *env, jobject thiz, jobject o) { + ptrToConvoInfo(env, thiz)->set(deserialize_legacy_closed_group(env, o)); +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_setClosedGroup( + JNIEnv *env, jobject thiz, jobject o) { + ptrToConvoInfo(env, thiz)->set(deserialize_closed_group(env, o)); +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_setBlindedOneToOne( + JNIEnv *env, jobject thiz, jobject o) { + ptrToConvoInfo(env, thiz)->set(deserialize_blinded_one_to_one(env, o)); +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructedBlindedOneToOne( + JNIEnv *env, jobject thiz, jstring blinded_id) { + return serialize_blinded_one_to_one(env, ptrToConvoInfo(env, thiz)->get_or_construct_blinded_1to1(jni_utils::JavaStringRef(env, blinded_id).view(), true)); +} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseBlindedOneToOne( + JNIEnv *env, jobject thiz, jstring blinded_id) { + return ptrToConvoInfo(env, thiz)->erase_blinded_1to1(jni_utils::JavaStringRef(env, blinded_id).view(), true); } diff --git a/library/src/main/cpp/conversation.h b/library/src/main/cpp/conversation.h index 75797e2..0d784b7 100644 --- a/library/src/main/cpp/conversation.h +++ b/library/src/main/cpp/conversation.h @@ -13,145 +13,5 @@ inline session::config::ConvoInfoVolatile *ptrToConvoInfo(JNIEnv *env, jobject o return (session::config::ConvoInfoVolatile *) env->GetLongField(obj, pointerField); } -inline jobject serialize_one_to_one(JNIEnv *env, session::config::convo::one_to_one one_to_one) { - auto clazz = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne")); - jmethodID constructor = env->GetMethodID(clazz.get(), "", "(Ljava/lang/String;JZ)V"); - auto account_id = jni_utils::JavaLocalRef(env, env->NewStringUTF(one_to_one.session_id.data())); - auto last_read = one_to_one.last_read; - auto unread = one_to_one.unread; - jobject serialized = env->NewObject(clazz.get(), constructor, account_id.get(), last_read, unread); - return serialized; -} - -inline jobject serialize_open_group(JNIEnv *env, session::config::convo::community community) { - auto clazz = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$Community")); - auto base_community = util::serialize_base_community(env, community); - jmethodID constructor = env->GetMethodID(clazz.get(), "", - "(Lnetwork/loki/messenger/libsession_util/util/BaseCommunityInfo;JZ)V"); - auto last_read = community.last_read; - auto unread = community.unread; - jobject serialized = env->NewObject(clazz.get(), constructor, base_community, last_read, unread); - return serialized; -} - -inline jobject serialize_legacy_group(JNIEnv *env, session::config::convo::legacy_group group) { - auto clazz = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyGroup")); - jmethodID constructor = env->GetMethodID(clazz.get(), "", "(Ljava/lang/String;JZ)V"); - auto group_id = jni_utils::JavaLocalRef(env, env->NewStringUTF(group.id.data())); - auto last_read = group.last_read; - auto unread = group.unread; - jobject serialized = env->NewObject(clazz.get(), constructor, group_id.get(), last_read, unread); - return serialized; -} - -inline jobject serialize_closed_group(JNIEnv* env, session::config::convo::group group) { - auto clazz = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$ClosedGroup")); - jmethodID constructor = env->GetMethodID(clazz.get(), "", "(Ljava/lang/String;JZ)V"); - auto session_id = jni_utils::JavaLocalRef(env, env->NewStringUTF(group.id.data())); - auto last_read = group.last_read; - auto unread = group.unread; - return env->NewObject(clazz.get(), constructor, session_id.get(), 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); - } else if (auto* og = std::get_if(&any)) { - return serialize_open_group(env, *og); - } else if (auto* lgc = std::get_if(&any)) { - return serialize_legacy_group(env, *lgc); - } else if (auto* gc = std::get_if(&any)) { - return serialize_closed_group(env, *gc); - } - return nullptr; -} - -inline session::config::convo::one_to_one deserialize_one_to_one(JNIEnv *env, jobject info, session::config::ConvoInfoVolatile *conf) { - auto clazz = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne")); - auto id_getter = env->GetFieldID(clazz.get(), "accountId", "Ljava/lang/String;"); - auto last_read_getter = env->GetFieldID(clazz.get(), "lastRead", "J"); - auto unread_getter = env->GetFieldID(clazz.get(), "unread", "Z"); - auto id = jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(info, id_getter))); - auto id_chars = env->GetStringUTFChars(id.get(), nullptr); - std::string id_string = std::string{id_chars}; - auto deserialized = conf->get_or_construct_1to1(id_string); - deserialized.last_read = env->GetLongField(info, last_read_getter); - deserialized.unread = env->GetBooleanField(info, unread_getter); - env->ReleaseStringUTFChars(id.get(), id_chars); - return deserialized; -} - -inline session::config::convo::community deserialize_community(JNIEnv *env, jobject info, session::config::ConvoInfoVolatile *conf) { - auto clazz = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$Community")); - auto base_community_getter = env->GetFieldID(clazz.get(), "baseCommunityInfo", "Lnetwork/loki/messenger/libsession_util/util/BaseCommunityInfo;"); - auto last_read_getter = env->GetFieldID(clazz.get(), "lastRead", "J"); - auto unread_getter = env->GetFieldID(clazz.get(), "unread", "Z"); - - auto base_community_info = jni_utils::JavaLocalRef(env, env->GetObjectField(info, base_community_getter)); - - auto base_community_deserialized = util::deserialize_base_community(env, base_community_info.get()); - auto deserialized = conf->get_or_construct_community( - base_community_deserialized.base_url(), - base_community_deserialized.room(), - base_community_deserialized.pubkey() - ); - - deserialized.last_read = env->GetLongField(info, last_read_getter); - deserialized.unread = env->GetBooleanField(info, unread_getter); - - return deserialized; -} - -inline session::config::convo::legacy_group deserialize_legacy_closed_group(JNIEnv *env, jobject info, session::config::ConvoInfoVolatile *conf) { - auto clazz = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyGroup")); - auto group_id_getter = env->GetFieldID(clazz.get(), "groupId", "Ljava/lang/String;"); - auto last_read_getter = env->GetFieldID(clazz.get(), "lastRead", "J"); - auto unread_getter = env->GetFieldID(clazz.get(), "unread", "Z"); - auto group_id = jni_utils::JavaLocalRef(env, static_cast(env->GetObjectField(info, group_id_getter))); - auto group_id_bytes = env->GetStringUTFChars(group_id.get(), nullptr); - auto group_id_string = std::string{group_id_bytes}; - auto deserialized = conf->get_or_construct_legacy_group(group_id_string); - deserialized.last_read = env->GetLongField(info, last_read_getter); - deserialized.unread = env->GetBooleanField(info, unread_getter); - env->ReleaseStringUTFChars(group_id.get(), group_id_bytes); - return deserialized; -} - -inline session::config::convo::group deserialize_closed_group(JNIEnv* env, jobject info, session::config::ConvoInfoVolatile* conf) { - auto clazz = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$ClosedGroup")); - auto id_getter = env->GetFieldID(clazz.get(), "accountId", "Ljava/lang/String;"); - auto last_read_getter = env->GetFieldID(clazz.get(), "lastRead", "J"); - auto unread_getter = env->GetFieldID(clazz.get(), "unread", "Z"); - auto session_id = (jstring)env->GetObjectField(info, id_getter); - auto session_id_bytes = env->GetStringUTFChars(session_id, nullptr); - auto last_read = env->GetLongField(info, last_read_getter); - auto unread = env->GetBooleanField(info, unread_getter); - - auto group = conf->get_or_construct_group(session_id_bytes); - group.last_read = last_read; - group.unread = unread; - - env->ReleaseStringUTFChars(session_id, session_id_bytes); - return group; -} - -inline std::optional deserialize_any(JNIEnv *env, jobject convo, session::config::ConvoInfoVolatile *conf) { - auto oto_class = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne")); - auto og_class = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$Community")); - auto lgc_class = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyGroup")); - auto gc_class = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/Conversation$ClosedGroup")); - - auto object_class = jni_utils::JavaLocalRef(env, env->GetObjectClass(convo)); - if (env->IsSameObject(object_class.get(), oto_class.get())) { - return session::config::convo::any{deserialize_one_to_one(env, convo, conf)}; - } else if (env->IsSameObject(object_class.get(), og_class.get())) { - return session::config::convo::any{deserialize_community(env, convo, conf)}; - } else if (env->IsSameObject(object_class.get(), lgc_class.get())) { - return session::config::convo::any{deserialize_legacy_closed_group(env, convo, conf)}; - } else if (env->IsSameObject(object_class.get(), gc_class.get())) { - return session::config::convo::any{deserialize_closed_group(env, convo, conf)}; - } - return std::nullopt; -} #endif //SESSION_ANDROID_CONVERSATION_H \ No newline at end of file diff --git a/library/src/main/cpp/group_info.cpp b/library/src/main/cpp/group_info.cpp index 825603b..bfc13a1 100644 --- a/library/src/main/cpp/group_info.cpp +++ b/library/src/main/cpp/group_info.cpp @@ -9,7 +9,6 @@ Java_network_loki_messenger_libsession_1util_GroupInfoConfig_00024Companion_newI jbyteArray pub_key, jbyteArray secret_key, jbyteArray initial_dump) { - std::lock_guard guard{util::util_mutex_}; std::optional> secret_key_optional{std::nullopt}; std::optional> initial_dump_optional{std::nullopt}; auto pub_key_bytes = util::vector_from_bytes(env, pub_key); @@ -30,7 +29,6 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_destroyGroup(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); group_info->destroy_group(); } @@ -39,7 +37,6 @@ Java_network_loki_messenger_libsession_1util_GroupInfoConfig_destroyGroup(JNIEnv extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_getCreated(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); return util::jlongFromOptional(env, group_info->get_created()); } @@ -47,7 +44,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_getDeleteAttachmentsBefore(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); return util::jlongFromOptional(env, group_info->get_delete_attach_before()); } @@ -55,7 +51,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_getDeleteBefore(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); return util::jlongFromOptional(env, group_info->get_delete_before()); } @@ -64,7 +59,6 @@ extern "C" JNIEXPORT jlong JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_getExpiryTimer(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); auto timer = group_info->get_expiry_timer(); if (!timer) { @@ -77,7 +71,6 @@ Java_network_loki_messenger_libsession_1util_GroupInfoConfig_getExpiryTimer(JNIE extern "C" JNIEXPORT jstring JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_getName(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); return util::jstringFromOptional(env, group_info->get_name()); } @@ -86,7 +79,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_getProfilePic(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); return util::serialize_user_pic(env, group_info->get_profile_pic()); } @@ -95,7 +87,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_isDestroyed(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); return group_info->is_destroyed(); } @@ -104,7 +95,6 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_setCreated(JNIEnv *env, jobject thiz, jlong created_at) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); group_info->set_created(created_at); } @@ -114,7 +104,6 @@ JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_setDeleteAttachmentsBefore(JNIEnv *env, jobject thiz, jlong delete_before) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); group_info->set_delete_attach_before(delete_before); } @@ -124,7 +113,6 @@ JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_setDeleteBefore(JNIEnv *env, jobject thiz, jlong delete_before) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); group_info->set_delete_before(delete_before); } @@ -134,7 +122,6 @@ JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_setExpiryTimer(JNIEnv *env, jobject thiz, jlong expire_seconds) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); group_info->set_expiry_timer(std::chrono::seconds{expire_seconds}); } @@ -143,11 +130,8 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_setName(JNIEnv *env, jobject thiz, jstring new_name) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); - auto bytes = env->GetStringUTFChars(new_name, nullptr); - group_info->set_name(bytes); - env->ReleaseStringUTFChars(new_name, bytes); + group_info->set_name(jni_utils::JavaStringRef(env, new_name).view()); } extern "C" @@ -155,20 +139,14 @@ JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_setProfilePic(JNIEnv *env, jobject thiz, jobject new_profile_pic) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); - auto user_pic = util::deserialize_user_pic(env, new_profile_pic); - auto url = env->GetStringUTFChars(user_pic.first, nullptr); - auto key = util::vector_from_bytes(env, user_pic.second); - group_info->set_profile_pic(url, key); - env->ReleaseStringUTFChars(user_pic.first, url); + group_info->set_profile_pic(util::deserialize_user_pic(env, new_profile_pic)); } extern "C" JNIEXPORT jlong JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_storageNamespace(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); return static_cast(group_info->storage_namespace()); } @@ -176,7 +154,6 @@ Java_network_loki_messenger_libsession_1util_GroupInfoConfig_storageNamespace(JN extern "C" JNIEXPORT jstring JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_id(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); return util::jstringFromOptional(env, group_info->id); } @@ -185,7 +162,6 @@ extern "C" JNIEXPORT jstring JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_getDescription(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); auto description = group_info->get_description(); if (!description) { @@ -200,9 +176,6 @@ JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupInfoConfig_setDescription(JNIEnv *env, jobject thiz, jstring new_description) { - std::lock_guard guard{util::util_mutex_}; auto group_info = ptrToInfo(env, thiz); - auto description = env->GetStringUTFChars(new_description, nullptr); - group_info->set_description(description); - env->ReleaseStringUTFChars(new_description, description); + group_info->set_description(jni_utils::JavaStringRef(env, new_description).view()); } \ No newline at end of file diff --git a/library/src/main/cpp/group_keys.cpp b/library/src/main/cpp/group_keys.cpp index cbe4650..45f87f7 100644 --- a/library/src/main/cpp/group_keys.cpp +++ b/library/src/main/cpp/group_keys.cpp @@ -22,7 +22,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_00024Companion_newI jlong info_pointer, jlong members_pointer) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; auto user_key_bytes = util::vector_from_bytes(env, user_secret_key); auto pub_key_bytes = util::vector_from_bytes(env, group_public_key); std::optional> secret_key_optional{std::nullopt}; @@ -55,7 +54,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_00024Companion_newI extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_groupKeys(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToKeys(env, thiz); return jni_utils::jlist_from_collection(env, config->group_keys(), util::bytes_from_span); } @@ -68,25 +66,23 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_loadKey(JNIEnv *env jlong timestamp_ms, jlong info_ptr, jlong members_ptr) { - std::lock_guard lock{util::util_mutex_}; auto keys = ptrToKeys(env, thiz); - auto message_bytes = util::vector_from_bytes(env, message); - auto hash_bytes = env->GetStringUTFChars(hash, nullptr); auto info = reinterpret_cast(info_ptr); auto members = reinterpret_cast(members_ptr); auto processed = jni_utils::run_catching_cxx_exception_or_throws(env, [&] { - return keys->load_key_message(hash_bytes, message_bytes, timestamp_ms, *info, *members); + return keys->load_key_message( + jni_utils::JavaStringRef(env, hash).view(), + jni_utils::JavaByteArrayRef(env, message).get(), + timestamp_ms, *info, *members); }); - env->ReleaseStringUTFChars(hash, hash_bytes); return processed; } extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_needsRekey(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto keys = ptrToKeys(env, thiz); return keys->needs_rekey(); } @@ -94,7 +90,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_needsRekey(JNIEnv * extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_needsDump(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto keys = ptrToKeys(env, thiz); return keys->needs_dump(); } @@ -104,7 +99,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_needsDump(JNIEnv *e extern "C" JNIEXPORT jbyteArray JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_pendingKey(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto keys = ptrToKeys(env, thiz); auto pending = keys->pending_key(); if (!pending) { @@ -118,7 +112,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_pendingConfig(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto keys = ptrToKeys(env, thiz); auto pending = keys->pending_config(); if (!pending) { @@ -132,7 +125,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_rekey(JNIEnv *env, jobject thiz, jlong info_ptr, jlong members_ptr) { - std::lock_guard lock{util::util_mutex_}; auto keys = ptrToKeys(env, thiz); auto info = reinterpret_cast(info_ptr); auto members = reinterpret_cast(members_ptr); @@ -144,7 +136,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_rekey(JNIEnv *env, extern "C" JNIEXPORT jbyteArray JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_dump(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto keys = ptrToKeys(env, thiz); auto dump = keys->dump(); auto byte_array = util::bytes_from_vector(env, dump); @@ -154,7 +145,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_dump(JNIEnv *env, j extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_free(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); delete ptr; } @@ -164,7 +154,6 @@ JNIEXPORT jbyteArray JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_encrypt(JNIEnv *env, jobject thiz, jbyteArray plaintext) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); auto plaintext_vector = util::vector_from_bytes(env, plaintext); auto enc = ptr->encrypt_message(plaintext_vector); @@ -177,7 +166,6 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_decrypt(JNIEnv *env, jobject thiz, jbyteArray ciphertext) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); auto ciphertext_vector = util::vector_from_bytes(env, ciphertext); auto decrypted = ptr->decrypt_message(ciphertext_vector); @@ -195,7 +183,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_decrypt(JNIEnv *env extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_keys(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); return jni_utils::jlist_from_collection(env, ptr->group_keys(), util::bytes_from_span); } @@ -204,7 +191,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_activeHashes(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); return jni_utils::jstring_list_from_collection(env, ptr->active_hashes()); } @@ -215,10 +201,8 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_makeSubAccount(JNIE jstring session_id, jboolean can_write, jboolean can_delete) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); - auto deserialized_id = util::string_from_jstring(env, session_id); - auto new_subaccount_key = ptr->swarm_make_subaccount(deserialized_id.data(), can_write, can_delete); + auto new_subaccount_key = ptr->swarm_make_subaccount(jni_utils::JavaStringRef(env, session_id).view(), can_write, can_delete); auto jbytes = util::bytes_from_vector(env, new_subaccount_key); return jbytes; } @@ -230,10 +214,8 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_getSubAccountToken( jstring session_id, jboolean can_write, jboolean can_delete) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); - auto deserialized_id = util::string_from_jstring(env, session_id); - auto token = ptr->swarm_subaccount_token(deserialized_id, can_write, can_delete); + auto token = ptr->swarm_subaccount_token(jni_utils::JavaStringRef(env, session_id).view(), can_write, can_delete); auto jbytes = util::bytes_from_vector(env, token); return jbytes; } @@ -244,7 +226,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_subAccountSign(JNIE jobject thiz, jbyteArray message, jbyteArray signing_value) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); auto message_vector = util::vector_from_bytes(env, message); auto signing_value_vector = util::vector_from_bytes(env, signing_value); @@ -257,11 +238,10 @@ JNIEXPORT jbyteArray JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_supplementFor(JNIEnv *env, jobject thiz, jobjectArray j_user_session_ids) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); std::vector user_session_ids; for (int i = 0, size = env->GetArrayLength(j_user_session_ids); i < size; i++) { - user_session_ids.push_back(util::string_from_jstring(env, (jstring)(env->GetObjectArrayElement(j_user_session_ids, i)))); + user_session_ids.push_back(jni_utils::JavaStringRef(env, jni_utils::JavaLocalRef(env, (jstring)(env->GetObjectArrayElement(j_user_session_ids, i))).get()).copy()); } auto supplement = ptr->key_supplement(user_session_ids); return util::bytes_from_vector(env, supplement); @@ -270,7 +250,6 @@ extern "C" JNIEXPORT jint JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_currentGeneration(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); return ptr->current_generation(); } @@ -278,7 +257,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_currentGeneration(J extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_admin(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); return ptr->admin(); } @@ -286,7 +264,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_admin(JNIEnv *env, extern "C" JNIEXPORT jint JNICALL Java_network_loki_messenger_libsession_1util_GroupKeysConfig_size(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); return ptr->size(); } @@ -297,7 +274,6 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_loadAdminKey(JNIEnv jbyteArray admin_key, jlong info_ptr, jlong members_ptr) { - std::lock_guard lock{util::util_mutex_}; auto ptr = ptrToKeys(env, thiz); auto admin_key_vector = util::vector_from_bytes(env, admin_key); auto info = reinterpret_cast(info_ptr); diff --git a/library/src/main/cpp/group_members.cpp b/library/src/main/cpp/group_members.cpp index f8ee6ea..8ef9c42 100644 --- a/library/src/main/cpp/group_members.cpp +++ b/library/src/main/cpp/group_members.cpp @@ -7,7 +7,6 @@ JNIEXPORT jlong JNICALL Java_network_loki_messenger_libsession_1util_GroupMembersConfig_00024Companion_newInstance( JNIEnv *env, jobject thiz, jbyteArray pub_key, jbyteArray secret_key, jbyteArray initial_dump) { - std::lock_guard lock{util::util_mutex_}; auto pub_key_bytes = util::vector_from_bytes(env, pub_key); std::optional> secret_key_optional{std::nullopt}; std::optional> initial_dump_optional{std::nullopt}; @@ -27,7 +26,6 @@ Java_network_loki_messenger_libsession_1util_GroupMembersConfig_00024Companion_n extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupMembersConfig_all(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToMembers(env, thiz); return jni_utils::jlist_from_collection(env, *config, util::serialize_group_member); } @@ -36,9 +34,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_GroupMembersConfig_erase(JNIEnv *env, jobject thiz, jstring pub_key_hex) { auto config = ptrToMembers(env, thiz); - auto member_id = env->GetStringUTFChars(pub_key_hex, nullptr); - auto erased = config->erase(member_id); - env->ReleaseStringUTFChars(pub_key_hex, member_id); + auto erased = config->erase(jni_utils::JavaStringRef(env, pub_key_hex).view()); return erased; } @@ -47,15 +43,12 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupMembersConfig_get(JNIEnv *env, jobject thiz, jstring pub_key_hex) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=]() -> jobject { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToMembers(env, thiz); - auto pub_key_bytes = env->GetStringUTFChars(pub_key_hex, nullptr); - auto member = config->get(pub_key_bytes); + auto member = config->get(jni_utils::JavaStringRef(env, pub_key_hex).view()); if (!member) { return nullptr; } auto serialized = util::serialize_group_member(env, *member); - env->ReleaseStringUTFChars(pub_key_hex, pub_key_bytes); return serialized; }); } @@ -65,12 +58,9 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_GroupMembersConfig_getOrConstruct(JNIEnv *env, jobject thiz, jstring pub_key_hex) { - std::lock_guard lock{util::util_mutex_}; auto config = ptrToMembers(env, thiz); - auto pub_key_bytes = env->GetStringUTFChars(pub_key_hex, nullptr); - auto member = config->get_or_construct(pub_key_bytes); + auto member = config->get_or_construct(jni_utils::JavaStringRef(env, pub_key_hex).view()); auto serialized = util::serialize_group_member(env, member); - env->ReleaseStringUTFChars(pub_key_hex, pub_key_bytes); return serialized; } @@ -78,7 +68,6 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_GroupMembersConfig_set(JNIEnv *env, jobject thiz, jobject group_member) { - std::lock_guard lock{util::util_mutex_}; ptrToMembers(env, thiz)->set(*ptrToMember(env, group_member)); } @@ -149,9 +138,7 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_util_GroupMember_setName(JNIEnv *env, jobject thiz, jstring name) { - auto name_bytes = env->GetStringUTFChars(name, nullptr); - ptrToMember(env, thiz)->set_name(name_bytes); - env->ReleaseStringUTFChars(name, name_bytes); + ptrToMember(env, thiz)->set_name(std::string(jni_utils::JavaStringRef(env, name).view())); } extern "C" @@ -199,12 +186,7 @@ JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_util_GroupMember_setProfilePic(JNIEnv *env, jobject thiz, jobject pic) { - const auto [jurl, jkey] = util::deserialize_user_pic(env, pic); - auto url = util::string_from_jstring(env, jurl); - auto key = util::vector_from_bytes(env, jkey); - auto &picture = ptrToMember(env, thiz)->profile_picture; - picture.url = url; - picture.key = key; + ptrToMember(env, thiz)->profile_picture = util::deserialize_user_pic(env, pic); } extern "C" @@ -228,5 +210,5 @@ Java_network_loki_messenger_libsession_1util_GroupMembersConfig_setPendingSend(J jobject thiz, jstring pub_key_hex, jboolean pending) { - ptrToMembers(env, thiz)->set_pending_send(util::string_from_jstring(env, pub_key_hex), pending); + ptrToMembers(env, thiz)->set_pending_send(jni_utils::JavaStringRef(env, pub_key_hex).copy(), pending); } \ No newline at end of file diff --git a/library/src/main/cpp/jni_utils.h b/library/src/main/cpp/jni_utils.h index ccef046..5aca809 100644 --- a/library/src/main/cpp/jni_utils.h +++ b/library/src/main/cpp/jni_utils.h @@ -171,6 +171,10 @@ namespace jni_utils { return std::string_view(data.data(), data.size()); } + std::string copy() const { + return std::string(view()); + } + // Get the data as a span. Only valid during the lifetime of this object. std::span get() const { return data; @@ -199,6 +203,10 @@ namespace jni_utils { std::span get() const { return data; } + + std::vector copy() const { + return std::vector(data.begin(), data.end()); + } }; } diff --git a/library/src/main/cpp/user_groups.cpp b/library/src/main/cpp/user_groups.cpp index ff73dca..2a60c3b 100644 --- a/library/src/main/cpp/user_groups.cpp +++ b/library/src/main/cpp/user_groups.cpp @@ -7,7 +7,6 @@ extern "C" JNIEXPORT jint JNICALL Java_network_loki_messenger_libsession_1util_util_GroupInfo_00024LegacyGroupInfo_00024Companion_NAME_1MAX_1LENGTH( JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; return session::config::legacy_group_info::NAME_MAX_LENGTH; } @@ -17,21 +16,15 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getCommunityInfo(J jobject thiz, jstring base_url, jstring room) { - std::lock_guard lock{util::util_mutex_}; 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; + auto community = conf->get_community(jni_utils::JavaStringRef(env, base_url).view(), jni_utils::JavaStringRef(env, room).view()); if (community) { - community_info = serialize_community_info(env, *community); + return serialize_community_info(env, *community); } - env->ReleaseStringUTFChars(base_url, base_url_bytes); - env->ReleaseStringUTFChars(room, room_bytes); - return community_info; + + return nullptr; } extern "C" @@ -39,15 +32,12 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getLegacyGroupInfo(JNIEnv *env, jobject thiz, jstring account_id) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - auto id_bytes = env->GetStringUTFChars(account_id, nullptr); - auto legacy_group = conf->get_legacy_group(id_bytes); + auto legacy_group = conf->get_legacy_group(jni_utils::JavaStringRef(env, account_id).view()); jobject return_group = nullptr; if (legacy_group) { return_group = serialize_legacy_group_info(env, *legacy_group); } - env->ReleaseStringUTFChars(account_id, id_bytes); return return_group; } @@ -55,17 +45,13 @@ 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) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - auto base_url_bytes = env->GetStringUTFChars(base_url, nullptr); - auto room_bytes = env->GetStringUTFChars(room, nullptr); - auto pub_hex_bytes = env->GetStringUTFChars(pub_key_hex, nullptr); - auto group = conf->get_or_construct_community(base_url_bytes, room_bytes, pub_hex_bytes); + auto group = conf->get_or_construct_community( + jni_utils::JavaStringRef(env, base_url).view(), + jni_utils::JavaStringRef(env, room).view(), + jni_utils::JavaStringRef(env, pub_key_hex).view()); - env->ReleaseStringUTFChars(base_url, base_url_bytes); - env->ReleaseStringUTFChars(room, room_bytes); - env->ReleaseStringUTFChars(pub_key_hex, pub_hex_bytes); return serialize_community_info(env, group); } @@ -73,11 +59,8 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getOrConstructLegacyGroupInfo( JNIEnv *env, jobject thiz, jstring account_id) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - auto id_bytes = env->GetStringUTFChars(account_id, nullptr); - auto group = conf->get_or_construct_legacy_group(id_bytes); - env->ReleaseStringUTFChars(account_id, id_bytes); + auto group = conf->get_or_construct_legacy_group(jni_utils::JavaStringRef(env, account_id).view()); return serialize_legacy_group_info(env, group); } @@ -85,7 +68,6 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_set__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_2( JNIEnv *env, jobject thiz, jobject group_info) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); auto community_info = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$CommunityGroupInfo"); auto legacy_info = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$LegacyGroupInfo"); @@ -109,7 +91,6 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_erase__Lnetwork_loki_messenger_libsession_1util_util_GroupInfo_2( JNIEnv *env, jobject thiz, jobject group_info) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); auto communityInfo = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$CommunityGroupInfo"); auto legacyInfo = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$LegacyGroupInfo"); @@ -131,7 +112,6 @@ extern "C" JNIEXPORT jlong JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_sizeCommunityInfo(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); return conf->size_communities(); } @@ -140,7 +120,6 @@ extern "C" JNIEXPORT jlong JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_sizeLegacyGroupInfo(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); return conf->size_legacy_groups(); } @@ -148,7 +127,6 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_sizeLegacyGroupInf extern "C" JNIEXPORT jlong JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_size(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToConvoInfo(env, thiz); return conf->size(); } @@ -171,7 +149,6 @@ inline jobject iterator_as_java_list(JNIEnv *env, session::config::UserGroups::i extern "C" 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); return iterator_as_java_list(env, conf->begin(), conf->end()); } @@ -180,7 +157,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_allCommunityInfo(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); return iterator_as_java_list(env, conf->begin_communities(), conf->end()); } @@ -189,7 +165,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_allLegacyGroupInfo(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); return iterator_as_java_list(env, conf->begin_legacy_groups(), conf->end()); } @@ -199,7 +174,6 @@ JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_eraseCommunity__Lnetwork_loki_messenger_libsession_1util_util_BaseCommunityInfo_2(JNIEnv *env, jobject thiz, jobject base_community_info) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); auto base_community = util::deserialize_base_community(env, base_community_info); return conf->erase_community(base_community.base_url(),base_community.room()); @@ -209,17 +183,14 @@ extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_eraseCommunity__Ljava_lang_String_2Ljava_lang_String_2( JNIEnv *env, jobject thiz, jstring server, jstring room) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - auto server_bytes = env->GetStringUTFChars(server, nullptr); - auto room_bytes = env->GetStringUTFChars(room, nullptr); - auto community = conf->get_community(server_bytes, room_bytes); + auto community = conf->get_community( + jni_utils::JavaStringRef(env, server).view(), + jni_utils::JavaStringRef(env, room).view()); bool deleted = false; if (community) { deleted = conf->erase(*community); } - env->ReleaseStringUTFChars(server, server_bytes); - env->ReleaseStringUTFChars(room, room_bytes); return deleted; } @@ -228,11 +199,8 @@ JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_eraseLegacyGroup(JNIEnv *env, jobject thiz, jstring account_id) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - auto account_id_bytes = env->GetStringUTFChars(account_id, nullptr); - bool return_bool = conf->erase_legacy_group(account_id_bytes); - env->ReleaseStringUTFChars(account_id, account_id_bytes); + bool return_bool = conf->erase_legacy_group(jni_utils::JavaStringRef(env, account_id).view()); return return_bool; } @@ -241,13 +209,8 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getClosedGroup(JNIEnv *env, jobject thiz, jstring session_id) { - std::lock_guard guard{util::util_mutex_}; auto config = ptrToUserGroups(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); + auto group = config->get_group(jni_utils::JavaStringRef(env, session_id).view()); if (group) { return serialize_closed_group_info(env, *group); @@ -260,14 +223,8 @@ JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getOrConstructClosedGroup(JNIEnv *env, jobject thiz, jstring session_id) { - std::lock_guard guard{util::util_mutex_}; auto config = ptrToUserGroups(env, thiz); - auto session_id_bytes = env->GetStringUTFChars(session_id, nullptr); - - auto group = config->get_or_construct_group(session_id_bytes); - - env->ReleaseStringUTFChars(session_id, session_id_bytes); - + auto group = config->get_or_construct_group(jni_utils::JavaStringRef(env, session_id).view()); return serialize_closed_group_info(env, group); } @@ -275,7 +232,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_allClosedGroupInfo(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); return iterator_as_java_list(env, conf->begin_groups(), conf->end()); } @@ -284,7 +240,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_createGroup(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto config = ptrToUserGroups(env, thiz); auto group = config->create_group(); @@ -295,7 +250,6 @@ extern "C" JNIEXPORT jlong JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_sizeClosedGroup(JNIEnv *env, jobject thiz) { - std::lock_guard guard{util::util_mutex_}; auto config = ptrToUserGroups(env, thiz); return config->size_groups(); } @@ -305,11 +259,8 @@ JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_eraseClosedGroup(JNIEnv *env, jobject thiz, jstring session_id) { - std::lock_guard guard{util::util_mutex_}; auto config = ptrToUserGroups(env, thiz); - auto session_id_bytes = env->GetStringUTFChars(session_id, nullptr); - bool return_value = config->erase_group(session_id_bytes); - env->ReleaseStringUTFChars(session_id, session_id_bytes); + bool return_value = config->erase_group(jni_utils::JavaStringRef(env, session_id).view()); return return_value; } @@ -323,10 +274,8 @@ Java_network_loki_messenger_libsession_1util_util_GroupInfo_00024ClosedGroupInfo return nullptr; } - auto seed_bytes = env->GetByteArrayElements(seed, nullptr); auto admin_key = session::ed25519::ed25519_key_pair( - std::span(reinterpret_cast(seed_bytes), 32)).second; - env->ReleaseByteArrayElements(seed, seed_bytes, 0); + jni_utils::JavaByteArrayRef(env, seed).get()).second; return util::bytes_from_span(env, std::span(admin_key.data(), admin_key.size())); } \ No newline at end of file diff --git a/library/src/main/cpp/user_groups.h b/library/src/main/cpp/user_groups.h index 17132f5..7efbafa 100644 --- a/library/src/main/cpp/user_groups.h +++ b/library/src/main/cpp/user_groups.h @@ -33,13 +33,11 @@ inline void deserialize_members_into(JNIEnv *env, jobject members_map, session:: auto iterator = jni_utils::JavaLocalRef(env, env->CallObjectMethod(entry_set.get(), get_at)); while (env->CallBooleanMethod(iterator.get(), has_next)) { - auto entry = jni_utils::JavaLocalRef(env, env->CallObjectMethod(iterator.get(), next)); - auto key = jni_utils::JavaLocalRef(env, static_cast(env->CallObjectMethod(entry.get(), get_key))); - auto boxed = jni_utils::JavaLocalRef(env, env->CallObjectMethod(entry.get(), get_value)); + jni_utils::JavaLocalRef entry(env, env->CallObjectMethod(iterator.get(), next)); + jni_utils::JavaLocalRef key(env, static_cast(env->CallObjectMethod(entry.get(), get_key))); + jni_utils::JavaLocalRef boxed(env, env->CallObjectMethod(entry.get(), get_value)); bool is_admin = env->CallBooleanMethod(boxed.get(), get_bool_value); - auto member_string = env->GetStringUTFChars(key.get(), nullptr); - to_append_group.insert(member_string, is_admin); - env->ReleaseStringUTFChars(key.get(), member_string); + to_append_group.insert(std::string(jni_utils::JavaStringRef(env, key.get()).view()), is_admin); } } @@ -61,25 +59,19 @@ inline session::config::legacy_group_info deserialize_legacy_group_info(JNIEnv * int priority = env->GetLongField(info, priority_field); long joined_at = env->GetLongField(info, joined_at_field); - auto id_bytes = util::string_from_jstring(env, id.get()); - auto name_bytes = env->GetStringUTFChars(name.get(), nullptr); - auto enc_pub_key_bytes = util::vector_from_bytes(env, enc_pub_key.get()); - auto enc_sec_key_bytes = util::vector_from_bytes(env, enc_sec_key.get()); - - auto info_deserialized = conf->get_or_construct_legacy_group(id_bytes); + auto info_deserialized = conf->get_or_construct_legacy_group(jni_utils::JavaStringRef(env, id.get()).view()); auto current_members = info_deserialized.members(); for (auto member = current_members.begin(); member != current_members.end(); ++member) { info_deserialized.erase(member->first); } deserialize_members_into(env, members_map.get(), info_deserialized); - info_deserialized.name = name_bytes; - info_deserialized.enc_pubkey = enc_pub_key_bytes; - info_deserialized.enc_seckey = enc_sec_key_bytes; + info_deserialized.name = jni_utils::JavaStringRef(env, name.get()).view(); + info_deserialized.enc_pubkey = jni_utils::JavaByteArrayRef(env, enc_pub_key.get()).copy(); + info_deserialized.enc_seckey = jni_utils::JavaByteArrayRef(env, enc_sec_key.get()).copy(); info_deserialized.priority = priority; info_deserialized.disappearing_timer = std::chrono::seconds(env->GetLongField(info, disappearing_timer_field)); info_deserialized.joined_at = joined_at; - env->ReleaseStringUTFChars(name.get(), name_bytes); return info_deserialized; } @@ -157,17 +149,15 @@ inline session::config::group_info deserialize_closed_group_info(JNIEnv* env, jo auto auth_jBytes = jni_utils::JavaLocalRef(env, (jbyteArray)env->CallObjectMethod(info_serialized, auth_method)); auto name_jstring = jni_utils::JavaLocalRef(env, (jstring)env->GetObjectField(info_serialized, name_field)); - auto id_bytes = util::string_from_jstring(env, id_jobject.get()); auto secret_bytes = util::vector_from_bytes(env, secret_jBytes.get()); auto auth_bytes = util::vector_from_bytes(env, auth_jBytes.get()); - auto name = util::string_from_jstring(env, name_jstring.get()); - session::config::group_info group_info(id_bytes); + session::config::group_info group_info(jni_utils::JavaStringRef(env, id_jobject.get()).copy()); group_info.auth_data = auth_bytes; group_info.secretkey = secret_bytes; group_info.priority = env->GetLongField(info_serialized, priority_field); group_info.invited = env->GetBooleanField(info_serialized, invited_field); - group_info.name = name; + group_info.name = jni_utils::JavaStringRef(env, name_jstring.get()).view(); group_info.joined_at = env->GetLongField(info_serialized, joined_at_field); if (env->GetBooleanField(info_serialized, kicked_field)) { diff --git a/library/src/main/cpp/user_profile.cpp b/library/src/main/cpp/user_profile.cpp index 254a561..a992f48 100644 --- a/library/src/main/cpp/user_profile.cpp +++ b/library/src/main/cpp/user_profile.cpp @@ -7,16 +7,12 @@ Java_network_loki_messenger_libsession_1util_UserProfile_setName( JNIEnv* env, jobject thiz, jstring newName) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); - auto name_chars = env->GetStringUTFChars(newName, nullptr); - profile->set_name(name_chars); - env->ReleaseStringUTFChars(newName, name_chars); + profile->set_name(jni_utils::JavaStringRef(env, newName).view()); } JNIEXPORT jstring JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_getName(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); auto name = profile->get_name(); if (name == std::nullopt) return nullptr; @@ -26,7 +22,6 @@ Java_network_loki_messenger_libsession_1util_UserProfile_getName(JNIEnv *env, jo JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_getPic(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); auto pic = profile->get_profile_pic(); @@ -38,13 +33,7 @@ Java_network_loki_messenger_libsession_1util_UserProfile_getPic(JNIEnv *env, job JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_setPic(JNIEnv *env, jobject thiz, jobject user_pic) { - std::lock_guard lock{util::util_mutex_}; - auto profile = ptrToProfile(env, thiz); - auto pic = util::deserialize_user_pic(env, user_pic); - auto url = env->GetStringUTFChars(pic.first, nullptr); - auto key = util::vector_from_bytes(env, pic.second); - profile->set_profile_pic(url, key); - env->ReleaseStringUTFChars(pic.first, url); + ptrToProfile(env, thiz)->set_profile_pic(util::deserialize_user_pic(env, user_pic)); } } @@ -52,14 +41,12 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_setNtsPriority(JNIEnv *env, jobject thiz, jlong priority) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); profile->set_nts_priority(priority); } extern "C" JNIEXPORT jlong JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_getNtsPriority(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); return profile->get_nts_priority(); } @@ -68,7 +55,6 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_setNtsExpiry(JNIEnv *env, jobject thiz, jobject expiry_mode) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); auto expiry = util::deserialize_expiry(env, expiry_mode); profile->set_nts_expiry(std::chrono::seconds (expiry.second)); @@ -77,7 +63,6 @@ Java_network_loki_messenger_libsession_1util_UserProfile_setNtsExpiry(JNIEnv *en extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_getNtsExpiry(JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); auto nts_expiry = profile->get_nts_expiry(); if (nts_expiry == std::nullopt) { @@ -92,7 +77,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_getCommunityMessageRequests( JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); auto blinded_msg_requests = profile->get_blinded_msgreqs(); if (blinded_msg_requests.has_value()) { @@ -105,7 +89,6 @@ extern "C" JNIEXPORT void JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_setCommunityMessageRequests( JNIEnv *env, jobject thiz, jboolean blocks) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); profile->set_blinded_msgreqs(std::optional{(bool)blocks}); } @@ -113,7 +96,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_UserProfile_isBlockCommunityMessageRequestsSet( JNIEnv *env, jobject thiz) { - std::lock_guard lock{util::util_mutex_}; auto profile = ptrToProfile(env, thiz); return profile->get_blinded_msgreqs().has_value(); } diff --git a/library/src/main/cpp/util.cpp b/library/src/main/cpp/util.cpp index 94c157d..36297cb 100644 --- a/library/src/main/cpp/util.cpp +++ b/library/src/main/cpp/util.cpp @@ -17,8 +17,6 @@ namespace util { - std::mutex util_mutex_ = std::mutex(); - jbyteArray bytes_from_vector(JNIEnv* env, const std::vector &from_str) { size_t length = from_str.size(); auto jlength = (jsize)length; @@ -31,13 +29,8 @@ namespace util { if (byteArray == nullptr) { return {}; } - size_t len = env->GetArrayLength(byteArray); - auto bytes = env->GetByteArrayElements(byteArray, nullptr); - auto begin = reinterpret_cast(bytes); - std::vector st{begin, begin + len}; - env->ReleaseByteArrayElements(byteArray, bytes, 0); - return st; + return jni_utils::JavaByteArrayRef(env, byteArray).copy(); } jbyteArray bytes_from_span(JNIEnv* env, std::span from_str) { @@ -48,29 +41,21 @@ namespace util { return new_array; } - std::string string_from_jstring(JNIEnv* env, jstring string) { - size_t len = env->GetStringUTFLength(string); - auto chars = env->GetStringUTFChars(string, nullptr); - - std::string st(chars, len); - env->ReleaseStringUTFChars(string, chars); - return st; - } - jobject serialize_user_pic(JNIEnv *env, session::config::profile_pic pic) { - auto returnObjectClass = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/UserPic")); + jni_utils::JavaLocalRef returnObjectClass(env, env->FindClass("network/loki/messenger/libsession_util/util/UserPic")); jmethodID constructor = env->GetMethodID(returnObjectClass.get(), "", "(Ljava/lang/String;Lnetwork/loki/messenger/libsession_util/util/Bytes;)V"); return env->NewObject(returnObjectClass.get(), constructor, - env->NewStringUTF(pic.url.data()), + jni_utils::JavaLocalRef(env, env->NewStringUTF(pic.url.data())).get(), jni_utils::session_bytes_from_range(env, pic.key) ); } - std::pair deserialize_user_pic(JNIEnv *env, jobject user_pic) { - auto userPicClass = jni_utils::JavaLocalRef(env, env->GetObjectClass(user_pic)); + + session::config::profile_pic deserialize_user_pic(JNIEnv *env, jobject user_pic) { + jni_utils::JavaLocalRef clazz(env, env->GetObjectClass(user_pic)); return { - static_cast(env->CallObjectMethod(user_pic, env->GetMethodID(userPicClass.get(), "getUrl", "()Ljava/lang/String;"))), - static_cast(env->CallObjectMethod(user_pic, env->GetMethodID(userPicClass.get(), "getKeyAsByteArray", "()[B"))) + jni_utils::JavaStringRef(env, (jstring) (env->CallObjectMethod(user_pic, env->GetMethodID(clazz.get(), "getUrl", "()Ljava/lang/String;")))).view(), + util::vector_from_bytes(env, static_cast(env->CallObjectMethod(user_pic, env->GetMethodID(clazz.get(), "getKeyAsByteArray", "()[B")))) }; } @@ -88,19 +73,15 @@ namespace util { jfieldID base_url_field = env->GetFieldID(base_community_clazz, "baseUrl", "Ljava/lang/String;"); jfieldID room_field = env->GetFieldID(base_community_clazz, "room", "Ljava/lang/String;"); jfieldID pubkey_hex_field = env->GetFieldID(base_community_clazz, "pubKeyHex", "Ljava/lang/String;"); - auto base_url = jni_utils::JavaLocalRef(env, (jstring)env->GetObjectField(base_community,base_url_field)); - auto room = jni_utils::JavaLocalRef(env, (jstring)env->GetObjectField(base_community, room_field)); - auto pub_key_hex = jni_utils::JavaLocalRef(env, (jstring)env->GetObjectField(base_community, pubkey_hex_field)); - auto base_url_chars = env->GetStringUTFChars(base_url.get(), nullptr); - auto room_chars = env->GetStringUTFChars(room.get(), nullptr); - auto pub_key_hex_chars = env->GetStringUTFChars(pub_key_hex.get(), nullptr); - - auto community = session::config::community(base_url_chars, room_chars, pub_key_hex_chars); - - env->ReleaseStringUTFChars(base_url.get(), base_url_chars); - env->ReleaseStringUTFChars(room.get(), room_chars); - env->ReleaseStringUTFChars(pub_key_hex.get(), pub_key_hex_chars); - return community; + jni_utils::JavaLocalRef base_url(env, (jstring)env->GetObjectField(base_community,base_url_field)); + jni_utils::JavaLocalRef room(env, (jstring)env->GetObjectField(base_community, room_field)); + jni_utils::JavaLocalRef pub_key_hex(env, (jstring)env->GetObjectField(base_community, pubkey_hex_field)); + + return session::config::community( + jni_utils::JavaStringRef(env, base_url.get()).view(), + jni_utils::JavaStringRef(env, room.get()).view(), + jni_utils::JavaStringRef(env, pub_key_hex.get()).view() + ); } jobject serialize_expiry(JNIEnv *env, const session::config::expiration_mode& mode, const std::chrono::seconds& time_seconds) { @@ -188,13 +169,11 @@ Java_network_loki_messenger_libsession_1util_util_MultiEncrypt_encryptForMultipl std::vector> message_vec{}; std::vector> recipient_vec{}; for (int i = 0; i < size; i++) { - jbyteArray message_j = static_cast(env->GetObjectArrayElement(messages, i)); - jbyteArray recipient_j = static_cast(env->GetObjectArrayElement(recipients, i)); - std::vector message = util::vector_from_bytes(env, message_j); - std::vector recipient = util::vector_from_bytes(env, recipient_j); + jni_utils::JavaLocalRef message_j(env, static_cast(env->GetObjectArrayElement(messages, i))); + jni_utils::JavaLocalRef recipient_j(env, static_cast(env->GetObjectArrayElement(recipients, i))); - message_vec.emplace_back(message); - recipient_vec.emplace_back(recipient); + message_vec.emplace_back(jni_utils::JavaByteArrayRef(env, message_j.get()).copy()); + recipient_vec.emplace_back(jni_utils::JavaByteArrayRef(env, recipient_j.get()).copy()); } std::vector> message_sv_vec{}; @@ -204,21 +183,17 @@ Java_network_loki_messenger_libsession_1util_util_MultiEncrypt_encryptForMultipl recipient_sv_vec.emplace_back(session::to_span(recipient_vec[i])); } - auto sk = util::vector_from_bytes(env, ed25519_secret_key); std::array random_nonce; randombytes_buf(random_nonce.data(), random_nonce.size()); - auto domain_string = env->GetStringUTFChars(domain, nullptr); - auto result = session::encrypt_for_multiple_simple( message_sv_vec, recipient_sv_vec, - sk, - domain_string, + jni_utils::JavaByteArrayRef(env, ed25519_secret_key).get(), + jni_utils::JavaStringRef(env, domain).view(), std::span {random_nonce.data(), 24} ); - env->ReleaseStringUTFChars(domain, domain_string); auto encoded = util::bytes_from_vector(env, result); return encoded; } @@ -231,17 +206,13 @@ Java_network_loki_messenger_libsession_1util_util_MultiEncrypt_decryptForMultipl jbyteArray secret_key, jbyteArray sender_pub_key, jstring domain) { - auto sk_vector = util::vector_from_bytes(env, secret_key); - auto encoded_vector = util::vector_from_bytes(env, encoded); - auto pub_vector = util::vector_from_bytes(env, sender_pub_key); - auto domain_bytes = env->GetStringUTFChars(domain, nullptr); auto result = session::decrypt_for_multiple_simple( - encoded_vector, - sk_vector, - pub_vector, - domain_bytes + jni_utils::JavaByteArrayRef(env, encoded).get(), + jni_utils::JavaByteArrayRef(env, secret_key).get(), + jni_utils::JavaByteArrayRef(env, sender_pub_key).get(), + jni_utils::JavaStringRef(env, domain).view() ); - env->ReleaseStringUTFChars(domain,domain_bytes); + if (result) { return util::bytes_from_vector(env, *result); } else { @@ -254,9 +225,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_util_BaseCommunityInfo_00024Companion_parseFullUrl( JNIEnv *env, jobject thiz, jstring full_url) { - auto bytes = env->GetStringUTFChars(full_url, nullptr); - auto [base, room, pk] = session::config::community::parse_full_url(bytes); - env->ReleaseStringUTFChars(full_url, bytes); + auto [base, room, pk] = session::config::community::parse_full_url(jni_utils::JavaStringRef(env, full_url).view()); jclass clazz = env->FindClass("kotlin/Triple"); jmethodID constructor = env->GetMethodID(clazz, "", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V"); diff --git a/library/src/main/cpp/util.h b/library/src/main/cpp/util.h index 5bf8436..6725ecd 100644 --- a/library/src/main/cpp/util.h +++ b/library/src/main/cpp/util.h @@ -6,6 +6,7 @@ #include #include #include + #include "session/types.hpp" #include "session/config/groups/info.hpp" #include "session/config/groups/keys.hpp" @@ -15,13 +16,11 @@ #include "session/config/expiring.hpp" namespace util { - extern std::mutex util_mutex_; jbyteArray bytes_from_vector(JNIEnv* env, const std::vector &from_str); std::vector vector_from_bytes(JNIEnv* env, jbyteArray byteArray); jbyteArray bytes_from_span(JNIEnv* env, std::span from_str); - std::string string_from_jstring(JNIEnv* env, jstring string); jobject serialize_user_pic(JNIEnv *env, session::config::profile_pic pic); - std::pair deserialize_user_pic(JNIEnv *env, jobject user_pic); + session::config::profile_pic deserialize_user_pic(JNIEnv *env, jobject user_pic); jobject serialize_base_community(JNIEnv *env, const session::config::community& base_community); 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); diff --git a/library/src/main/java/network/loki/messenger/libsession_util/Config.kt b/library/src/main/java/network/loki/messenger/libsession_util/Config.kt index f356a4e..d177bf5 100644 --- a/library/src/main/java/network/loki/messenger/libsession_util/Config.kt +++ b/library/src/main/java/network/loki/messenger/libsession_util/Config.kt @@ -1,6 +1,7 @@ package network.loki.messenger.libsession_util import network.loki.messenger.libsession_util.util.BaseCommunityInfo +import network.loki.messenger.libsession_util.util.BlindedContact import network.loki.messenger.libsession_util.util.ConfigPush import network.loki.messenger.libsession_util.util.Contact import network.loki.messenger.libsession_util.util.Conversation @@ -45,58 +46,28 @@ interface MutableConfig : ReadableConfig { fun dirty(): Boolean } -sealed class ConfigBase(pointer: Long): Config(pointer), MutableConfig { - companion object { - init { - System.loadLibrary("session_util") - } - external fun kindFor(configNamespace: Int): Class - - const val PRIORITY_HIDDEN = -1L - const val PRIORITY_VISIBLE = 0L - const val PRIORITY_PINNED = 1L - - } - - external override fun dirty(): Boolean - external override fun needsPush(): Boolean - external override fun needsDump(): Boolean - external override fun push(): ConfigPush - external override fun dump(): ByteArray - external override fun encryptionDomain(): String - external override fun confirmPushed(seqNo: Long, hashes: Array) - external fun merge(toMerge: Array>): List - external override fun activeHashes(): List -} - interface ReadableContacts: ReadableConfig { fun get(accountId: String): Contact? fun all(): List + + fun allBlinded(): List + + fun getBlinded(blindedId: String): BlindedContact? } interface MutableContacts : ReadableContacts, MutableConfig { fun getOrConstruct(accountId: String): Contact fun set(contact: Contact) fun erase(accountId: String): Boolean -} -class Contacts private constructor(pointer: Long) : ConfigBase(pointer), MutableContacts { - constructor(ed25519SecretKey: ByteArray, initialDump: ByteArray? = null) : this( - createConfigObject( - "Contacts", - ed25519SecretKey, - initialDump - ) - ) - - override fun namespace() = Namespace.CONTACTS() - - external override fun get(accountId: String): Contact? - external override fun getOrConstruct(accountId: String): Contact - external override fun all(): List - external override fun set(contact: Contact) - external override fun erase(accountId: String): Boolean + fun getOrConstructBlinded( + communityServerUrl: String, + communityServerPubKeyHex: String, + blindedId: String + ): BlindedContact + fun setBlinded(contact: BlindedContact) + fun eraseBlinded(communityServerUrl: String, blindedId: String) } interface ReadableUserProfile: ReadableConfig { @@ -116,30 +87,6 @@ interface MutableUserProfile : ReadableUserProfile, MutableConfig { fun setCommunityMessageRequests(blocks: Boolean) } -class UserProfile private constructor(pointer: Long) : ConfigBase(pointer), MutableUserProfile { - constructor(ed25519SecretKey: ByteArray, initialDump: ByteArray? = null) : this( - createConfigObject( - "UserProfile", - ed25519SecretKey, - initialDump - ) - ) - - override fun namespace() = Namespace.USER_PROFILE() - - external override fun setName(newName: String) - external override fun getName(): String? - external override fun getPic(): UserPic - external override fun setPic(userPic: UserPic) - external override fun setNtsPriority(priority: Long) - external override fun getNtsPriority(): Long - external override fun setNtsExpiry(expiryMode: ExpiryMode) - external override fun getNtsExpiry(): ExpiryMode - external override fun getCommunityMessageRequests(): Boolean - external override fun setCommunityMessageRequests(blocks: Boolean) - external override fun isBlockCommunityMessageRequestsSet(): Boolean -} - interface ReadableConversationVolatileConfig: ReadableConfig { fun getOneToOne(pubKeyHex: String): Conversation.OneToOne? fun getCommunity(baseUrl: String, room: String): Conversation.Community? @@ -162,76 +109,31 @@ interface ReadableConversationVolatileConfig: ReadableConfig { interface MutableConversationVolatileConfig : ReadableConversationVolatileConfig, MutableConfig { fun getOrConstructOneToOne(pubKeyHex: String): Conversation.OneToOne fun eraseOneToOne(pubKeyHex: String): Boolean + fun setOneToOne(o: Conversation.OneToOne) fun getOrConstructCommunity(baseUrl: String, room: String, pubKeyHex: String): Conversation.Community fun getOrConstructCommunity(baseUrl: String, room: String, pubKey: ByteArray): Conversation.Community fun eraseCommunity(community: Conversation.Community): Boolean fun eraseCommunity(baseUrl: String, room: String): Boolean + fun setCommunity(o: Conversation.Community) fun getOrConstructLegacyGroup(groupId: String): Conversation.LegacyGroup fun eraseLegacyClosedGroup(groupId: String): Boolean + fun setLegacyGroup(o: Conversation.LegacyGroup) fun getOrConstructClosedGroup(sessionId: String): Conversation.ClosedGroup fun eraseClosedGroup(sessionId: String): Boolean + fun setClosedGroup(o: Conversation.ClosedGroup) - fun erase(conversation: Conversation): Boolean - fun set(toStore: Conversation) + fun getOrConstructedBlindedOneToOne(blindedId: String): Conversation.BlindedOneToOne + fun eraseBlindedOneToOne(blindedId: String): Boolean + fun setBlindedOneToOne(o: Conversation.BlindedOneToOne) + fun set(conv: Conversation) fun eraseAll(predicate: (Conversation) -> Boolean): Int } -class ConversationVolatileConfig private constructor(pointer: Long): ConfigBase(pointer), MutableConversationVolatileConfig { - constructor(ed25519SecretKey: ByteArray, initialDump: ByteArray? = null) : this( - createConfigObject( - "ConvoInfoVolatile", - ed25519SecretKey, - initialDump - ) - ) - - override fun namespace() = Namespace.CONVO_INFO_VOLATILE() - - external override fun getOneToOne(pubKeyHex: String): Conversation.OneToOne? - external override fun getOrConstructOneToOne(pubKeyHex: String): Conversation.OneToOne - external override fun eraseOneToOne(pubKeyHex: String): Boolean - - external override fun getCommunity(baseUrl: String, room: String): Conversation.Community? - external override fun getOrConstructCommunity(baseUrl: String, room: String, pubKeyHex: String): Conversation.Community - external override fun getOrConstructCommunity(baseUrl: String, room: String, pubKey: ByteArray): Conversation.Community - external override fun eraseCommunity(community: Conversation.Community): Boolean - external override fun eraseCommunity(baseUrl: String, room: String): Boolean - - external override fun getLegacyClosedGroup(groupId: String): Conversation.LegacyGroup? - external override fun getOrConstructLegacyGroup(groupId: String): Conversation.LegacyGroup - external override fun eraseLegacyClosedGroup(groupId: String): Boolean - - external override fun getClosedGroup(sessionId: String): Conversation.ClosedGroup? - external override fun getOrConstructClosedGroup(sessionId: String): Conversation.ClosedGroup - external override fun eraseClosedGroup(sessionId: String): Boolean - - external override fun erase(conversation: Conversation): Boolean - external override fun set(toStore: Conversation) - - /** - * Erase all conversations that do not satisfy the `predicate`, similar to [MutableList.removeAll] - */ - external override fun eraseAll(predicate: (Conversation) -> Boolean): Int - - external override fun sizeOneToOnes(): Int - external override fun sizeCommunities(): Int - external override fun sizeLegacyClosedGroups(): Int - external override fun size(): Int - - external override fun empty(): Boolean - - external override fun allOneToOnes(): List - external override fun allCommunities(): List - external override fun allLegacyClosedGroups(): List - external override fun allClosedGroups(): List - external override fun all(): List -} - interface ReadableUserGroupsConfig : ReadableConfig { fun getCommunityInfo(baseUrl: String, room: String): GroupInfo.CommunityGroupInfo? fun getLegacyGroupInfo(accountId: String): GroupInfo.LegacyGroupInfo? @@ -259,40 +161,6 @@ interface MutableUserGroupsConfig : ReadableUserGroupsConfig, MutableConfig { fun eraseClosedGroup(accountId: String): Boolean } -class UserGroupsConfig private constructor(pointer: Long): ConfigBase(pointer), MutableUserGroupsConfig { - constructor(ed25519SecretKey: ByteArray, initialDump: ByteArray? = null) : this( - createConfigObject( - "UserGroups", - ed25519SecretKey, - initialDump - ) - ) - - override fun namespace() = Namespace.USER_GROUPS() - - external override fun getCommunityInfo(baseUrl: String, room: String): GroupInfo.CommunityGroupInfo? - external override fun getLegacyGroupInfo(accountId: String): GroupInfo.LegacyGroupInfo? - external override fun getClosedGroup(accountId: String): GroupInfo.ClosedGroupInfo? - external override fun getOrConstructCommunityInfo(baseUrl: String, room: String, pubKeyHex: String): GroupInfo.CommunityGroupInfo - external override fun getOrConstructLegacyGroupInfo(accountId: String): GroupInfo.LegacyGroupInfo - external override fun getOrConstructClosedGroup(accountId: String): GroupInfo.ClosedGroupInfo - external override fun set(groupInfo: GroupInfo) - external override fun erase(groupInfo: GroupInfo) - external override fun eraseCommunity(baseCommunityInfo: BaseCommunityInfo): Boolean - external override fun eraseCommunity(server: String, room: String): Boolean - external override fun eraseLegacyGroup(accountId: String): Boolean - external override fun eraseClosedGroup(accountId: String): Boolean - external override fun sizeCommunityInfo(): Long - external override fun sizeLegacyGroupInfo(): Long - external override fun sizeClosedGroup(): Long - external override fun size(): Long - external override fun all(): List - external override fun allCommunityInfo(): List - external override fun allLegacyGroupInfo(): List - external override fun allClosedGroupInfo(): List - external override fun createGroup(): GroupInfo.ClosedGroupInfo -} - interface ReadableGroupInfoConfig: ReadableConfig { fun id(): String fun getDeleteAttachmentsBefore(): Long? @@ -317,40 +185,6 @@ interface MutableGroupInfoConfig : ReadableGroupInfoConfig, MutableConfig { fun destroyGroup() } -class GroupInfoConfig private constructor(pointer: Long): ConfigBase(pointer), MutableGroupInfoConfig { - constructor(groupPubKey: ByteArray, groupAdminKey: ByteArray?, initialDump: ByteArray?) - : this(newInstance(groupPubKey, groupAdminKey, initialDump)) - - companion object { - private external fun newInstance( - pubKey: ByteArray, - secretKey: ByteArray?, - initialDump: ByteArray? - ): Long - } - - override fun namespace() = Namespace.GROUP_INFO() - - external override fun id(): String - external override fun destroyGroup() - external override fun getCreated(): Long? - external override fun getDeleteAttachmentsBefore(): Long? - external override fun getDeleteBefore(): Long? - external override fun getExpiryTimer(): Long - external override fun getName(): String? - external override fun getProfilePic(): UserPic - external override fun isDestroyed(): Boolean - external override fun setCreated(createdAt: Long) - external override fun setDeleteAttachmentsBefore(deleteBefore: Long) - external override fun setDeleteBefore(deleteBefore: Long) - external override fun setExpiryTimer(expireSeconds: Long) - external override fun setName(newName: String) - external override fun getDescription(): String - external override fun setDescription(newDescription: String) - external override fun setProfilePic(newProfilePic: UserPic) - external override fun storageNamespace(): Long -} - interface ReadableGroupMembersConfig: ReadableConfig { fun all(): List @@ -383,34 +217,6 @@ interface MutableGroupMembersConfig : ReadableGroupMembersConfig, MutableConfig fun setPendingSend(pubKeyHex: String, pending: Boolean) } -class GroupMembersConfig private constructor(pointer: Long): ConfigBase(pointer), MutableGroupMembersConfig { - companion object { - private external fun newInstance( - pubKey: ByteArray, - secretKey: ByteArray?, - initialDump: ByteArray? - ): Long - } - - constructor(groupPubKey: ByteArray, groupAdminKey: ByteArray?, initialDump: ByteArray?) - : this(newInstance(groupPubKey, groupAdminKey, initialDump)) - - override fun namespace() = Namespace.GROUP_MEMBERS() - - external override fun all(): List - external override fun erase(pubKeyHex: String): Boolean - external override fun get(pubKeyHex: String): GroupMember? - external override fun getOrConstruct(pubKeyHex: String): GroupMember - external override fun set(groupMember: GroupMember) - external override fun setPendingSend(pubKeyHex: String, pending: Boolean) - - private external fun statusInt(groupMember: GroupMember): Int - override fun status(groupMember: GroupMember): GroupMember.Status { - val statusInt = statusInt(groupMember) - return GroupMember.Status.entries.first { it.nativeValue == statusInt } - } -} - sealed class ConfigSig(pointer: Long) : Config(pointer) interface ReadableGroupKeysConfig { @@ -437,96 +243,7 @@ interface MutableGroupKeysConfig : ReadableGroupKeysConfig { fun loadAdminKey(adminKey: ByteArray) } -class GroupKeysConfig private constructor( - pointer: Long, - private val info: GroupInfoConfig, - private val members: GroupMembersConfig -): ConfigSig(pointer), MutableGroupKeysConfig { - companion object { - private external fun newInstance( - userSecretKey: ByteArray, - groupPublicKey: ByteArray, - groupSecretKey: ByteArray? = null, - initialDump: ByteArray?, - infoPtr: Long, - members: Long - ): Long - } - - constructor( - userSecretKey: ByteArray, - groupPublicKey: ByteArray, - groupAdminKey: ByteArray?, - initialDump: ByteArray?, - info: GroupInfoConfig, - members: GroupMembersConfig - ) : this( - newInstance( - userSecretKey, - groupPublicKey, - groupAdminKey, - initialDump, - info.pointer, - members.pointer - ), - info, - members - ) - - override fun namespace() = Namespace.GROUP_KEYS() - - external override fun groupKeys(): List - external override fun needsDump(): Boolean - external override fun dump(): ByteArray - external fun loadKey(message: ByteArray, - hash: String, - timestampMs: Long, - infoPtr: Long, - membersPtr: Long): Boolean - - override fun loadKey(message: ByteArray, hash: String, timestampMs: Long): Boolean { - return loadKey(message, hash, timestampMs, info.pointer, members.pointer) - } - - override fun loadAdminKey(adminKey: ByteArray) { - loadAdminKey(adminKey, info.pointer, members.pointer) - } - - private external fun loadAdminKey(adminKey: ByteArray, infoPtr: Long, membersPtr: Long) - - external override fun needsRekey(): Boolean - external override fun pendingKey(): ByteArray? - private external fun supplementFor(userSessionIds: Array): ByteArray - override fun supplementFor(userSessionIds: List): ByteArray { - return supplementFor(userSessionIds.toTypedArray()) - } - - external override fun pendingConfig(): ByteArray? - external override fun activeHashes(): List - external fun rekey(infoPtr: Long, membersPtr: Long): ByteArray - - external override fun encrypt(plaintext: ByteArray): ByteArray - external override fun decrypt(ciphertext: ByteArray): Pair? - - external override fun keys(): List - - external override fun makeSubAccount(sessionId: String, canWrite: Boolean, canDelete: Boolean): ByteArray - external override fun getSubAccountToken(sessionId: String, canWrite: Boolean, canDelete: Boolean): ByteArray - - external override fun subAccountSign(message: ByteArray, signingValue: ByteArray): SwarmAuth - - external override fun currentGeneration(): Int - external fun admin(): Boolean - external override fun size(): Int - - data class SwarmAuth( - val subAccount: String, - val subAccountSig: String, - val signature: String - ) -} - -private external fun createConfigObject( +external fun createConfigObject( configName: String, ed25519SecretKey: ByteArray, initialDump: ByteArray? diff --git a/library/src/main/java/network/loki/messenger/libsession_util/ConfigBase.kt b/library/src/main/java/network/loki/messenger/libsession_util/ConfigBase.kt new file mode 100644 index 0000000..f0c8bc0 --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/ConfigBase.kt @@ -0,0 +1,27 @@ +package network.loki.messenger.libsession_util + +import network.loki.messenger.libsession_util.util.ConfigPush + +sealed class ConfigBase(pointer: Long): Config(pointer), MutableConfig { + companion object { + init { + System.loadLibrary("session_util") + } + external fun kindFor(configNamespace: Int): Class + + const val PRIORITY_HIDDEN = -1L + const val PRIORITY_VISIBLE = 0L + const val PRIORITY_PINNED = 1L + + } + + external override fun dirty(): Boolean + external override fun needsPush(): Boolean + external override fun needsDump(): Boolean + external override fun push(): ConfigPush + external override fun dump(): ByteArray + external override fun encryptionDomain(): String + external override fun confirmPushed(seqNo: Long, hashes: Array) + external fun merge(toMerge: Array>): List + external override fun activeHashes(): List +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/Contacts.kt b/library/src/main/java/network/loki/messenger/libsession_util/Contacts.kt new file mode 100644 index 0000000..36d47fa --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/Contacts.kt @@ -0,0 +1,40 @@ +package network.loki.messenger.libsession_util + +import network.loki.messenger.libsession_util.util.BlindedContact +import network.loki.messenger.libsession_util.util.Contact + +class Contacts private constructor(pointer: Long) : ConfigBase(pointer), MutableContacts { + constructor(ed25519SecretKey: ByteArray, initialDump: ByteArray? = null) : this( + createConfigObject( + "Contacts", + ed25519SecretKey, + initialDump + ) + ) + + override fun namespace() = Namespace.CONTACTS() + + external override fun get(accountId: String): Contact? + external override fun getOrConstruct(accountId: String): Contact + external override fun all(): List + external override fun set(contact: Contact) + external override fun erase(accountId: String): Boolean + external override fun getOrConstructBlinded( + communityServerUrl: String, + communityServerPubKeyHex: String, + blindedId: String + ): BlindedContact + + external override fun setBlinded(contact: BlindedContact) + + external override fun eraseBlinded( + communityServerUrl: String, + blindedId: String + ) + + external override fun allBlinded(): List + + external override fun getBlinded( + blindedId: String + ): BlindedContact? +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/ConversationVolatileConfig.kt b/library/src/main/java/network/loki/messenger/libsession_util/ConversationVolatileConfig.kt new file mode 100644 index 0000000..e3e4c5d --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/ConversationVolatileConfig.kt @@ -0,0 +1,69 @@ +package network.loki.messenger.libsession_util + +import network.loki.messenger.libsession_util.util.Conversation + +class ConversationVolatileConfig private constructor(pointer: Long): ConfigBase(pointer), MutableConversationVolatileConfig { + constructor(ed25519SecretKey: ByteArray, initialDump: ByteArray? = null) : this( + createConfigObject( + "ConvoInfoVolatile", + ed25519SecretKey, + initialDump + ) + ) + + override fun namespace() = Namespace.CONVO_INFO_VOLATILE() + + external override fun getOneToOne(pubKeyHex: String): Conversation.OneToOne? + external override fun getOrConstructOneToOne(pubKeyHex: String): Conversation.OneToOne + external override fun eraseOneToOne(pubKeyHex: String): Boolean + external override fun setOneToOne(o: Conversation.OneToOne) + + external override fun getCommunity(baseUrl: String, room: String): Conversation.Community? + external override fun getOrConstructCommunity(baseUrl: String, room: String, pubKeyHex: String): Conversation.Community + external override fun getOrConstructCommunity(baseUrl: String, room: String, pubKey: ByteArray): Conversation.Community + external override fun eraseCommunity(community: Conversation.Community): Boolean + external override fun eraseCommunity(baseUrl: String, room: String): Boolean + external override fun setCommunity(o: Conversation.Community) + + external override fun getLegacyClosedGroup(groupId: String): Conversation.LegacyGroup? + external override fun getOrConstructLegacyGroup(groupId: String): Conversation.LegacyGroup + external override fun eraseLegacyClosedGroup(groupId: String): Boolean + external override fun setLegacyGroup(o: Conversation.LegacyGroup) + + external override fun getClosedGroup(sessionId: String): Conversation.ClosedGroup? + external override fun getOrConstructClosedGroup(sessionId: String): Conversation.ClosedGroup + external override fun eraseClosedGroup(sessionId: String): Boolean + external override fun setClosedGroup(o: Conversation.ClosedGroup) + + external override fun setBlindedOneToOne(o: Conversation.BlindedOneToOne) + external override fun getOrConstructedBlindedOneToOne(blindedId: String): Conversation.BlindedOneToOne + external override fun eraseBlindedOneToOne(blindedId: String): Boolean + + override fun set(conv: Conversation) { + when (conv) { + is Conversation.BlindedOneToOne -> setBlindedOneToOne(conv) + is Conversation.ClosedGroup -> setClosedGroup(conv) + is Conversation.Community -> setCommunity(conv) + is Conversation.LegacyGroup -> setLegacyGroup(conv) + is Conversation.OneToOne -> setOneToOne(conv) + } + } + + /** + * Erase all conversations that do not satisfy the `predicate`, similar to [MutableList.removeAll] + */ + external override fun eraseAll(predicate: (Conversation) -> Boolean): Int + + external override fun sizeOneToOnes(): Int + external override fun sizeCommunities(): Int + external override fun sizeLegacyClosedGroups(): Int + external override fun size(): Int + + external override fun empty(): Boolean + + external override fun allOneToOnes(): List + external override fun allCommunities(): List + external override fun allLegacyClosedGroups(): List + external override fun allClosedGroups(): List + external override fun all(): List +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/GroupInfoConfig.kt b/library/src/main/java/network/loki/messenger/libsession_util/GroupInfoConfig.kt new file mode 100644 index 0000000..7056315 --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/GroupInfoConfig.kt @@ -0,0 +1,37 @@ +package network.loki.messenger.libsession_util + +import network.loki.messenger.libsession_util.util.UserPic + +class GroupInfoConfig private constructor(pointer: Long): ConfigBase(pointer), MutableGroupInfoConfig { + constructor(groupPubKey: ByteArray, groupAdminKey: ByteArray?, initialDump: ByteArray?) + : this(newInstance(groupPubKey, groupAdminKey, initialDump)) + + companion object { + private external fun newInstance( + pubKey: ByteArray, + secretKey: ByteArray?, + initialDump: ByteArray? + ): Long + } + + override fun namespace() = Namespace.GROUP_INFO() + + external override fun id(): String + external override fun destroyGroup() + external override fun getCreated(): Long? + external override fun getDeleteAttachmentsBefore(): Long? + external override fun getDeleteBefore(): Long? + external override fun getExpiryTimer(): Long + external override fun getName(): String? + external override fun getProfilePic(): UserPic + external override fun isDestroyed(): Boolean + external override fun setCreated(createdAt: Long) + external override fun setDeleteAttachmentsBefore(deleteBefore: Long) + external override fun setDeleteBefore(deleteBefore: Long) + external override fun setExpiryTimer(expireSeconds: Long) + external override fun setName(newName: String) + external override fun getDescription(): String + external override fun setDescription(newDescription: String) + external override fun setProfilePic(newProfilePic: UserPic) + external override fun storageNamespace(): Long +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/GroupKeysConfig.kt b/library/src/main/java/network/loki/messenger/libsession_util/GroupKeysConfig.kt new file mode 100644 index 0000000..4f7fff9 --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/GroupKeysConfig.kt @@ -0,0 +1,90 @@ +package network.loki.messenger.libsession_util + +class GroupKeysConfig private constructor( + pointer: Long, + private val info: GroupInfoConfig, + private val members: GroupMembersConfig +): ConfigSig(pointer), MutableGroupKeysConfig { + companion object { + private external fun newInstance( + userSecretKey: ByteArray, + groupPublicKey: ByteArray, + groupSecretKey: ByteArray? = null, + initialDump: ByteArray?, + infoPtr: Long, + members: Long + ): Long + } + + constructor( + userSecretKey: ByteArray, + groupPublicKey: ByteArray, + groupAdminKey: ByteArray?, + initialDump: ByteArray?, + info: GroupInfoConfig, + members: GroupMembersConfig + ) : this( + newInstance( + userSecretKey, + groupPublicKey, + groupAdminKey, + initialDump, + info.pointer, + members.pointer + ), + info, + members + ) + + override fun namespace() = Namespace.GROUP_KEYS() + + external override fun groupKeys(): List + external override fun needsDump(): Boolean + external override fun dump(): ByteArray + external fun loadKey(message: ByteArray, + hash: String, + timestampMs: Long, + infoPtr: Long, + membersPtr: Long): Boolean + + override fun loadKey(message: ByteArray, hash: String, timestampMs: Long): Boolean { + return loadKey(message, hash, timestampMs, info.pointer, members.pointer) + } + + override fun loadAdminKey(adminKey: ByteArray) { + loadAdminKey(adminKey, info.pointer, members.pointer) + } + + private external fun loadAdminKey(adminKey: ByteArray, infoPtr: Long, membersPtr: Long) + + external override fun needsRekey(): Boolean + external override fun pendingKey(): ByteArray? + private external fun supplementFor(userSessionIds: Array): ByteArray + override fun supplementFor(userSessionIds: List): ByteArray { + return supplementFor(userSessionIds.toTypedArray()) + } + + external override fun pendingConfig(): ByteArray? + external override fun activeHashes(): List + external fun rekey(infoPtr: Long, membersPtr: Long): ByteArray + + external override fun encrypt(plaintext: ByteArray): ByteArray + external override fun decrypt(ciphertext: ByteArray): Pair? + + external override fun keys(): List + + external override fun makeSubAccount(sessionId: String, canWrite: Boolean, canDelete: Boolean): ByteArray + external override fun getSubAccountToken(sessionId: String, canWrite: Boolean, canDelete: Boolean): ByteArray + + external override fun subAccountSign(message: ByteArray, signingValue: ByteArray): SwarmAuth + + external override fun currentGeneration(): Int + external fun admin(): Boolean + external override fun size(): Int + + data class SwarmAuth( + val subAccount: String, + val subAccountSig: String, + val signature: String + ) +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/GroupMembersConfig.kt b/library/src/main/java/network/loki/messenger/libsession_util/GroupMembersConfig.kt new file mode 100644 index 0000000..2a6c726 --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/GroupMembersConfig.kt @@ -0,0 +1,31 @@ +package network.loki.messenger.libsession_util + +import network.loki.messenger.libsession_util.util.GroupMember + +class GroupMembersConfig private constructor(pointer: Long): ConfigBase(pointer), MutableGroupMembersConfig { + companion object { + private external fun newInstance( + pubKey: ByteArray, + secretKey: ByteArray?, + initialDump: ByteArray? + ): Long + } + + constructor(groupPubKey: ByteArray, groupAdminKey: ByteArray?, initialDump: ByteArray?) + : this(newInstance(groupPubKey, groupAdminKey, initialDump)) + + override fun namespace() = Namespace.GROUP_MEMBERS() + + external override fun all(): List + external override fun erase(pubKeyHex: String): Boolean + external override fun get(pubKeyHex: String): GroupMember? + external override fun getOrConstruct(pubKeyHex: String): GroupMember + external override fun set(groupMember: GroupMember) + external override fun setPendingSend(pubKeyHex: String, pending: Boolean) + + private external fun statusInt(groupMember: GroupMember): Int + override fun status(groupMember: GroupMember): GroupMember.Status { + val statusInt = statusInt(groupMember) + return GroupMember.Status.entries.first { it.nativeValue == statusInt } + } +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/UserGroupsConfig.kt b/library/src/main/java/network/loki/messenger/libsession_util/UserGroupsConfig.kt new file mode 100644 index 0000000..8072616 --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/UserGroupsConfig.kt @@ -0,0 +1,38 @@ +package network.loki.messenger.libsession_util + +import network.loki.messenger.libsession_util.util.BaseCommunityInfo +import network.loki.messenger.libsession_util.util.GroupInfo + +class UserGroupsConfig private constructor(pointer: Long): ConfigBase(pointer), MutableUserGroupsConfig { + constructor(ed25519SecretKey: ByteArray, initialDump: ByteArray? = null) : this( + createConfigObject( + "UserGroups", + ed25519SecretKey, + initialDump + ) + ) + + override fun namespace() = Namespace.USER_GROUPS() + + external override fun getCommunityInfo(baseUrl: String, room: String): GroupInfo.CommunityGroupInfo? + external override fun getLegacyGroupInfo(accountId: String): GroupInfo.LegacyGroupInfo? + external override fun getClosedGroup(accountId: String): GroupInfo.ClosedGroupInfo? + external override fun getOrConstructCommunityInfo(baseUrl: String, room: String, pubKeyHex: String): GroupInfo.CommunityGroupInfo + external override fun getOrConstructLegacyGroupInfo(accountId: String): GroupInfo.LegacyGroupInfo + external override fun getOrConstructClosedGroup(accountId: String): GroupInfo.ClosedGroupInfo + external override fun set(groupInfo: GroupInfo) + external override fun erase(groupInfo: GroupInfo) + external override fun eraseCommunity(baseCommunityInfo: BaseCommunityInfo): Boolean + external override fun eraseCommunity(server: String, room: String): Boolean + external override fun eraseLegacyGroup(accountId: String): Boolean + external override fun eraseClosedGroup(accountId: String): Boolean + external override fun sizeCommunityInfo(): Long + external override fun sizeLegacyGroupInfo(): Long + external override fun sizeClosedGroup(): Long + external override fun size(): Long + external override fun all(): List + external override fun allCommunityInfo(): List + external override fun allLegacyGroupInfo(): List + external override fun allClosedGroupInfo(): List + external override fun createGroup(): GroupInfo.ClosedGroupInfo +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/UserProfile.kt b/library/src/main/java/network/loki/messenger/libsession_util/UserProfile.kt new file mode 100644 index 0000000..3f8b7ee --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/UserProfile.kt @@ -0,0 +1,28 @@ +package network.loki.messenger.libsession_util + +import network.loki.messenger.libsession_util.util.ExpiryMode +import network.loki.messenger.libsession_util.util.UserPic + +class UserProfile private constructor(pointer: Long) : ConfigBase(pointer), MutableUserProfile { + constructor(ed25519SecretKey: ByteArray, initialDump: ByteArray? = null) : this( + createConfigObject( + "UserProfile", + ed25519SecretKey, + initialDump + ) + ) + + override fun namespace() = Namespace.USER_PROFILE() + + external override fun setName(newName: String) + external override fun getName(): String? + external override fun getPic(): UserPic + external override fun setPic(userPic: UserPic) + external override fun setNtsPriority(priority: Long) + external override fun getNtsPriority(): Long + external override fun setNtsExpiry(expiryMode: ExpiryMode) + external override fun getNtsExpiry(): ExpiryMode + external override fun getCommunityMessageRequests(): Boolean + external override fun setCommunityMessageRequests(blocks: Boolean) + external override fun isBlockCommunityMessageRequestsSet(): Boolean +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/util/BaseCommunity.kt b/library/src/main/java/network/loki/messenger/libsession_util/util/BaseCommunity.kt index a48d082..e56a9ac 100644 --- a/library/src/main/java/network/loki/messenger/libsession_util/util/BaseCommunity.kt +++ b/library/src/main/java/network/loki/messenger/libsession_util/util/BaseCommunity.kt @@ -7,5 +7,6 @@ data class BaseCommunityInfo(val baseUrl: String, val room: String, val pubKeyHe } external fun parseFullUrl(fullUrl: String): Triple? } + external fun fullUrl(): String } \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/util/BlindedContact.kt b/library/src/main/java/network/loki/messenger/libsession_util/util/BlindedContact.kt new file mode 100644 index 0000000..134ebb5 --- /dev/null +++ b/library/src/main/java/network/loki/messenger/libsession_util/util/BlindedContact.kt @@ -0,0 +1,14 @@ +package network.loki.messenger.libsession_util.util + +data class BlindedContact( + val id: String, + val communityServer: String, + val communityServerPubKeyHex: String, + var name: String, + var createdEpochSeconds: Long, + var profilePic: UserPic +) { + @OptIn(ExperimentalStdlibApi::class) + val communityServerPubKey: ByteArray + get() = communityServerPubKeyHex.hexToByteArray() +} \ No newline at end of file diff --git a/library/src/main/java/network/loki/messenger/libsession_util/util/Contact.kt b/library/src/main/java/network/loki/messenger/libsession_util/util/Contact.kt index 7f0c290..1816c05 100644 --- a/library/src/main/java/network/loki/messenger/libsession_util/util/Contact.kt +++ b/library/src/main/java/network/loki/messenger/libsession_util/util/Contact.kt @@ -8,6 +8,8 @@ data class Contact( var approvedMe: Boolean = false, var blocked: Boolean = false, var profilePicture: UserPic = UserPic.DEFAULT, + var createdEpochSeconds: Long = 0, + var profileUpdatedEpochSeconds: Long = 0, var priority: Long = 0, var expiryMode: ExpiryMode = ExpiryMode.NONE, ) { diff --git a/library/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt b/library/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt index 6f34670..d7e2ca3 100644 --- a/library/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt +++ b/library/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt @@ -28,4 +28,10 @@ sealed class Conversation { override var lastRead: Long, override var unread: Boolean ): Conversation() + + data class BlindedOneToOne( + val blindedAccountId: String, + override var lastRead: Long, + override var unread: Boolean + ) : Conversation() } \ No newline at end of file diff --git a/libsession-util b/libsession-util index 95b9fe7..551a48b 160000 --- a/libsession-util +++ b/libsession-util @@ -1 +1 @@ -Subproject commit 95b9fe74d1c419487f6e69458db1ebc2bb824a2a +Subproject commit 551a48b258f53a36c4cd1ad036d65e3dcd575fbc