From 68b62c3e80ac0e85c4ed0ff8cd6837b313b5c0c9 Mon Sep 17 00:00:00 2001 From: 0x330a <92654767+0x330a@users.noreply.github.com> Date: Tue, 13 Dec 2022 17:40:09 +1100 Subject: [PATCH] feat: adding in new contacts functionality and wrappers, sorting out multiple files to organize all the wrapper functions --- libsession-util/libsession-util | 2 +- .../libsession_util/InstrumentedTests.kt | 10 +- libsession-util/src/main/cpp/CMakeLists.txt | 10 +- libsession-util/src/main/cpp/config_base.cpp | 80 +++++++ libsession-util/src/main/cpp/config_base.h | 14 ++ libsession-util/src/main/cpp/contacts.cpp | 39 ++++ libsession-util/src/main/cpp/contacts.h | 32 +++ libsession-util/src/main/cpp/session_util.cpp | 217 ------------------ libsession-util/src/main/cpp/user_profile.cpp | 78 +++++++ libsession-util/src/main/cpp/user_profile.h | 14 ++ libsession-util/src/main/cpp/util.cpp | 60 +++++ libsession-util/src/main/cpp/util.h | 17 ++ .../loki/messenger/libsession_util/Config.kt | 14 +- .../messenger/libsession_util/util/Contact.kt | 11 + 14 files changed, 374 insertions(+), 224 deletions(-) create mode 100644 libsession-util/src/main/cpp/config_base.cpp create mode 100644 libsession-util/src/main/cpp/config_base.h create mode 100644 libsession-util/src/main/cpp/contacts.cpp create mode 100644 libsession-util/src/main/cpp/contacts.h delete mode 100644 libsession-util/src/main/cpp/session_util.cpp create mode 100644 libsession-util/src/main/cpp/user_profile.cpp create mode 100644 libsession-util/src/main/cpp/user_profile.h create mode 100644 libsession-util/src/main/cpp/util.cpp create mode 100644 libsession-util/src/main/cpp/util.h create mode 100644 libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Contact.kt diff --git a/libsession-util/libsession-util b/libsession-util/libsession-util index b47ce1b3be..94b14f212a 160000 --- a/libsession-util/libsession-util +++ b/libsession-util/libsession-util @@ -1 +1 @@ -Subproject commit b47ce1b3be84cac7cf051ef851c3c3de58381b26 +Subproject commit 94b14f212a14fd846f1737cd6180fff4f06d42f5 diff --git a/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt b/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt index e27c39b46e..5c3bb44445 100644 --- a/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt +++ b/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt @@ -32,6 +32,12 @@ class InstrumentedTests { assertEquals("network.loki.messenger.libsession_util.test", appContext.packageName) } + @Test + fun jni_contacts() { + val userProfile = UserProfile.newInstance(keyPair.secretKey) + + } + @Test fun jni_accessible() { val userProfile = UserProfile.newInstance(keyPair.secretKey) @@ -173,8 +179,8 @@ class InstrumentedTests { assertEquals(3, userConfigMerge.seqNo) - assertEquals("Raz", newConf.getName()) - assertEquals("Raz", userProfile.getName()) + assertEquals("Nibbler", newConf.getName()) + assertEquals("Nibbler", userProfile.getName()) userProfile.free() newConf.free() diff --git a/libsession-util/src/main/cpp/CMakeLists.txt b/libsession-util/src/main/cpp/CMakeLists.txt index 17fc99b4ee..7836bb7adf 100644 --- a/libsession-util/src/main/cpp/CMakeLists.txt +++ b/libsession-util/src/main/cpp/CMakeLists.txt @@ -22,14 +22,18 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(STATIC_BUNDLE ON) add_subdirectory(../../../libsession-util libsession) +set(SOURCES + user_profile.cpp + config_base.cpp + contacts.cpp + util.cpp) + add_library( # Sets the name of the library. session_util - # Sets the library as a shared library. SHARED - # Provides a relative path to your source file(s). - session_util.cpp) + ${SOURCES}) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by diff --git a/libsession-util/src/main/cpp/config_base.cpp b/libsession-util/src/main/cpp/config_base.cpp new file mode 100644 index 0000000000..0c79b68c60 --- /dev/null +++ b/libsession-util/src/main/cpp/config_base.cpp @@ -0,0 +1,80 @@ +#include "config_base.h" +#include "util.h" + +extern "C" { +JNIEXPORT jboolean JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_dirty(JNIEnv *env, jobject thiz) { + auto* configBase = ptrToConfigBase(env, thiz); + return configBase->is_dirty(); +} + +JNIEXPORT jboolean JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_needsPush(JNIEnv *env, jobject thiz) { + auto config = ptrToConfigBase(env, thiz); + return config->needs_push(); +} + +JNIEXPORT jboolean JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_needsDump(JNIEnv *env, jobject thiz) { + auto config = ptrToConfigBase(env, thiz); + return config->needs_dump(); +} + +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_push(JNIEnv *env, jobject thiz) { + auto config = ptrToConfigBase(env, thiz); + auto pair = config->push(); + session::ustring to_push_str = pair.first; + jbyteArray returnByteArray = util::bytes_from_ustring(env, to_push_str); + jlong seqNo = pair.second; + jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/ConfigWithSeqNo"); + jmethodID methodId = env->GetMethodID(returnObjectClass, "", "([BJ)V"); + jobject returnObject = env->NewObject(returnObjectClass, methodId, returnByteArray, seqNo); + return returnObject; +} + +JNIEXPORT jbyteArray JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_dump(JNIEnv *env, jobject thiz) { + auto config = ptrToConfigBase(env, thiz); + auto dumped = config->dump(); + jbyteArray bytes = util::bytes_from_ustring(env, dumped); + return bytes; +} + +JNIEXPORT jstring JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_encryptionDomain(JNIEnv *env, + jobject thiz) { + auto conf = ptrToConfigBase(env, thiz); + return env->NewStringUTF(conf->encryption_domain()); +} + +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_confirmPushed(JNIEnv *env, jobject thiz, + jlong seq_no) { + auto conf = ptrToConfigBase(env, thiz); + conf->confirm_pushed(seq_no); +} + +JNIEXPORT jint JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3_3B(JNIEnv *env, jobject thiz, + jobjectArray to_merge) { + auto conf = ptrToConfigBase(env, thiz); + size_t number = env->GetArrayLength(to_merge); + std::vector configs = {}; + for (int i = 0; i < number; i++) { + auto jArr = (jbyteArray) env->GetObjectArrayElement(to_merge, i); + auto bytes = util::ustring_from_bytes(env, jArr); + configs.push_back(bytes); + } + return conf->merge(configs); +} + +JNIEXPORT jint JNICALL +Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3B(JNIEnv *env, jobject thiz, + jbyteArray to_merge) { + auto conf = ptrToConfigBase(env, thiz); + std::vector configs = {util::ustring_from_bytes(env, to_merge)}; + return conf->merge(configs); +} + +} \ No newline at end of file diff --git a/libsession-util/src/main/cpp/config_base.h b/libsession-util/src/main/cpp/config_base.h new file mode 100644 index 0000000000..9ce520b198 --- /dev/null +++ b/libsession-util/src/main/cpp/config_base.h @@ -0,0 +1,14 @@ +#ifndef SESSION_ANDROID_CONFIG_BASE_H +#define SESSION_ANDROID_CONFIG_BASE_H + +#include "session/config/base.hpp" +#include +#include + +inline session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj) { + jclass baseClass = env->FindClass("network/loki/messenger/libsession_util/ConfigBase"); + jfieldID pointerField = env->GetFieldID(baseClass, "pointer", "J"); + return (session::config::ConfigBase*) env->GetLongField(obj, pointerField); +} + +#endif \ No newline at end of file diff --git a/libsession-util/src/main/cpp/contacts.cpp b/libsession-util/src/main/cpp/contacts.cpp new file mode 100644 index 0000000000..fec6e3115b --- /dev/null +++ b/libsession-util/src/main/cpp/contacts.cpp @@ -0,0 +1,39 @@ +#include "contacts.h" +#include "util.h" + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_get(JNIEnv *env, jobject thiz, + jstring session_id) { + auto contacts = ptrToContacts(env, thiz); + auto contact = contacts->get(env->GetStringUTFChars(session_id, nullptr)); + if (!contact) return nullptr; + jobject j_contact = serialize_contact(env, contact.value()); + return j_contact; +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_getOrCreate(JNIEnv *env, jobject thiz, + jstring session_id) { + auto contacts = ptrToContacts(env, thiz); + auto contact = contacts->get_or_create(env->GetStringUTFChars(session_id, nullptr)); + return serialize_contact(env, contact); +} + +extern "C" +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_set(JNIEnv *env, jobject thiz, + jobject contact) { + auto contacts = ptrToContacts(env, thiz); + auto contact_info = deserialize_contact(env, contact); + contacts->set(contact_info); +} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_network_loki_messenger_libsession_1util_Contacts_erase(JNIEnv *env, jobject thiz, + jstring session_id) { + auto contacts = ptrToContacts(env, thiz); + return contacts->erase(env->GetStringUTFChars(session_id, nullptr)); +} \ No newline at end of file diff --git a/libsession-util/src/main/cpp/contacts.h b/libsession-util/src/main/cpp/contacts.h new file mode 100644 index 0000000000..8f8fd097b7 --- /dev/null +++ b/libsession-util/src/main/cpp/contacts.h @@ -0,0 +1,32 @@ +#ifndef SESSION_ANDROID_CONTACTS_H +#define SESSION_ANDROID_CONTACTS_H + +#include +#include "session/config/contacts.hpp" + +inline session::config::Contacts *ptrToContacts(JNIEnv *env, jobject obj) { + jclass contactsClass = env->FindClass("network/loki/messenger/libsession_util/Contacts"); + jfieldID pointerField = env->GetFieldID(contactsClass, "pointer", "J"); + return (session::config::Contacts *) env->GetLongField(obj, pointerField); +} + +inline jobject serialize_contact(JNIEnv *env, session::config::contact_info info) { + jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact"); + jmethodID constructor = env->GetMethodID(contactClass, "", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZLnetwork/loki/messenger/libsession_util/util/UserPic;)V"); + // val id: String, + // val name: String, + // val nickname: String, + // val approved: Boolean, + // val approvedMe: Boolean, + // val blocked: Boolean, + // val profilePicture: UserPic + return nullptr; +} + +inline session::config::contact_info deserialize_contact(JNIEnv *env, jobject info) { + +} + + +#endif //SESSION_ANDROID_CONTACTS_H diff --git a/libsession-util/src/main/cpp/session_util.cpp b/libsession-util/src/main/cpp/session_util.cpp deleted file mode 100644 index df524b3a95..0000000000 --- a/libsession-util/src/main/cpp/session_util.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include -#include -#include "session/config/user_profile.hpp" - -session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj) { - jclass baseClass = env->FindClass("network/loki/messenger/libsession_util/ConfigBase"); - jfieldID pointerField = env->GetFieldID(baseClass, "pointer", "J"); - return (session::config::ConfigBase*) env->GetLongField(obj, pointerField); -} - -session::config::UserProfile* ptrToProfile(JNIEnv* env, jobject obj) { - jclass configClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile"); - jfieldID pointerField = env->GetFieldID(configClass, "pointer", "J"); - return (session::config::UserProfile*) env->GetLongField(obj, pointerField); -} - -jbyteArray bytes_from_ustring(JNIEnv* env, session::ustring_view from_str) { - size_t length = from_str.length(); - jsize jlength = (jsize)length; - jbyteArray new_array = env->NewByteArray(jlength); - env->SetByteArrayRegion(new_array, 0, jlength, (jbyte*)from_str.data()); - return new_array; -} - -session::ustring ustring_from_bytes(JNIEnv* env, jbyteArray byteArray) { - size_t len = env->GetArrayLength(byteArray); - jbyte* bytes = env->GetByteArrayElements(byteArray, nullptr); - session::ustring newSt((u_char*)bytes, len); - env->ReleaseByteArrayElements(byteArray, bytes, 0); - return newSt; -} - -extern "C" -JNIEXPORT jobject JNICALL -Java_network_loki_messenger_libsession_1util_UserProfile_00024Companion_newInstance___3B_3B( - JNIEnv *env, jobject thiz, jbyteArray ed25519_secret_key, jbyteArray initial_dump) { - auto secret_key = ustring_from_bytes(env, ed25519_secret_key); - auto initial = ustring_from_bytes(env, initial_dump); - auto* profile = new session::config::UserProfile(secret_key, std::optional(initial)); - - jclass userClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile"); - jmethodID constructor = env->GetMethodID(userClass, "", "(J)V"); - jobject newConfig = env->NewObject(userClass, constructor, reinterpret_cast(profile)); - - return newConfig; -} - -extern "C" JNIEXPORT jobject JNICALL -Java_network_loki_messenger_libsession_1util_UserProfile_00024Companion_newInstance___3B( - JNIEnv* env, - jobject, - jbyteArray secretKey) { - - auto* profile = new session::config::UserProfile(ustring_from_bytes(env, secretKey), std::nullopt); - - jclass userClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile"); - jmethodID constructor = env->GetMethodID(userClass, "", "(J)V"); - jobject newConfig = env->NewObject(userClass, constructor, reinterpret_cast(profile)); - - return newConfig; -} - -extern "C" JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_UserProfile_setName( - JNIEnv* env, - jobject thiz, - jstring newName) { - auto profile = ptrToProfile(env, thiz); - profile->set_name(env->GetStringUTFChars(newName, nullptr)); -} - -extern "C" -JNIEXPORT jstring JNICALL -Java_network_loki_messenger_libsession_1util_UserProfile_getName(JNIEnv *env, jobject thiz) { - auto profile = ptrToProfile(env, thiz); - auto name = profile->get_name(); - if (name == std::nullopt) return nullptr; - jstring returnString = env->NewStringUTF(name->data()); - return returnString; -} - -extern "C" -JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_UserProfile_free(JNIEnv *env, jobject thiz) { - auto profile = ptrToProfile(env, thiz); - delete profile; -} - -extern "C" -JNIEXPORT jboolean JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_dirty(JNIEnv *env, jobject thiz) { - auto* configBase = ptrToConfigBase(env, thiz); - return configBase->is_dirty(); -} - -extern "C" -JNIEXPORT jboolean JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_needsPush(JNIEnv *env, jobject thiz) { - auto config = ptrToConfigBase(env, thiz); - return config->needs_push(); -} - -extern "C" -JNIEXPORT jboolean JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_needsDump(JNIEnv *env, jobject thiz) { - auto config = ptrToConfigBase(env, thiz); - return config->needs_dump(); -} - -extern "C" -JNIEXPORT jobject JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_push(JNIEnv *env, jobject thiz) { - auto config = ptrToConfigBase(env, thiz); - auto pair = config->push(); - session::ustring to_push_str = pair.first; - jbyteArray returnByteArray = bytes_from_ustring(env, to_push_str); - jlong seqNo = pair.second; - jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/ConfigWithSeqNo"); - jmethodID methodId = env->GetMethodID(returnObjectClass, "", "([BJ)V"); - jobject returnObject = env->NewObject(returnObjectClass, methodId, returnByteArray, seqNo); - return returnObject; -} - -extern "C" -JNIEXPORT jobject JNICALL -Java_network_loki_messenger_libsession_1util_UserProfile_getPic(JNIEnv *env, jobject thiz) { - auto profile = ptrToProfile(env, thiz); - auto pic = profile->get_profile_pic(); - if (pic == std::nullopt) return nullptr; - // return nullptr if either parameter is null as per profile class - jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/UserPic"); - jmethodID constructor = env->GetMethodID(returnObjectClass, "", "(Ljava/lang/String;[B)V"); - jstring url = env->NewStringUTF(pic->url.data()); - jbyteArray byteArray = bytes_from_ustring(env, pic->key); - jobject returnObject = env->NewObject(returnObjectClass, constructor, url, byteArray); - return returnObject; -} -extern "C" -JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_UserProfile_setPic(JNIEnv *env, jobject thiz, - jobject user_pic) { - auto profile = ptrToProfile(env, thiz); - jclass userPicClass = env->FindClass("network/loki/messenger/libsession_util/util/UserPic"); - jfieldID picField = env->GetFieldID(userPicClass, "url", "Ljava/lang/String;"); - jfieldID keyField = env->GetFieldID(userPicClass, "key", "[B"); - auto pic = (jstring)env->GetObjectField(user_pic, picField); - auto key = (jbyteArray)env->GetObjectField(user_pic, keyField); - - const char* pic_chars = env->GetStringUTFChars(pic, nullptr); - auto key_str = ustring_from_bytes(env, key); - auto* pic_string = new std::string(pic_chars); - - profile->set_profile_pic(*pic_string, key_str); -} -extern "C" -JNIEXPORT jbyteArray JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_dump(JNIEnv *env, jobject thiz) { - auto config = ptrToConfigBase(env, thiz); - auto dumped = config->dump(); - jbyteArray bytes = bytes_from_ustring(env, dumped); - return bytes; -} -extern "C" -JNIEXPORT jobject JNICALL -Java_network_loki_messenger_libsession_1util_util_Sodium_ed25519KeyPair(JNIEnv *env, jobject thiz, jbyteArray seed) { - std::array ed_pk; - std::array ed_sk; - auto seed_bytes = ustring_from_bytes(env, seed); - crypto_sign_ed25519_seed_keypair(ed_pk.data(), ed_sk.data(), seed_bytes.data()); - - jclass kp_class = env->FindClass("network/loki/messenger/libsession_util/util/KeyPair"); - jmethodID kp_constructor = env->GetMethodID(kp_class, "", "([B[B)V"); - - jbyteArray pk_jarray = bytes_from_ustring(env, session::ustring_view {ed_pk.data(), ed_pk.size()}); - jbyteArray sk_jarray = bytes_from_ustring(env, session::ustring_view {ed_sk.data(), ed_sk.size()}); - - jobject return_obj = env->NewObject(kp_class, kp_constructor, pk_jarray, sk_jarray); - return return_obj; -} -extern "C" -JNIEXPORT jstring JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_encryptionDomain(JNIEnv *env, - jobject thiz) { - auto conf = ptrToConfigBase(env, thiz); - return env->NewStringUTF(conf->encryption_domain()); -} -extern "C" -JNIEXPORT void JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_confirmPushed(JNIEnv *env, jobject thiz, - jlong seq_no) { - auto conf = ptrToConfigBase(env, thiz); - conf->confirm_pushed(seq_no); -} -extern "C" -JNIEXPORT jint JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3_3B(JNIEnv *env, jobject thiz, - jobjectArray to_merge) { - auto conf = ptrToConfigBase(env, thiz); - size_t number = env->GetArrayLength(to_merge); - std::vector configs = {}; - for (int i = 0; i < number; i++) { - auto jArr = (jbyteArray) env->GetObjectArrayElement(to_merge, i); - auto bytes = ustring_from_bytes(env, jArr); - configs.push_back(bytes); - } - return conf->merge(configs); -} - -extern "C" -JNIEXPORT jint JNICALL -Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3B(JNIEnv *env, jobject thiz, - jbyteArray to_merge) { - auto conf = ptrToConfigBase(env, thiz); - std::vector configs = {ustring_from_bytes(env, to_merge)}; - return conf->merge(configs); -} \ No newline at end of file diff --git a/libsession-util/src/main/cpp/user_profile.cpp b/libsession-util/src/main/cpp/user_profile.cpp new file mode 100644 index 0000000000..20c8e5182d --- /dev/null +++ b/libsession-util/src/main/cpp/user_profile.cpp @@ -0,0 +1,78 @@ +#include "user_profile.h" +#include "util.h" + +extern "C" { +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_UserProfile_00024Companion_newInstance___3B_3B( + JNIEnv *env, jobject thiz, jbyteArray ed25519_secret_key, jbyteArray initial_dump) { + auto secret_key = util::ustring_from_bytes(env, ed25519_secret_key); + auto initial = util::ustring_from_bytes(env, initial_dump); + auto* profile = new session::config::UserProfile(secret_key, std::optional(initial)); + + jclass userClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile"); + jmethodID constructor = env->GetMethodID(userClass, "", "(J)V"); + jobject newConfig = env->NewObject(userClass, constructor, reinterpret_cast(profile)); + + return newConfig; +} + +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_UserProfile_00024Companion_newInstance___3B( + JNIEnv* env, + jobject, + jbyteArray secretKey) { + + auto* profile = new session::config::UserProfile(util::ustring_from_bytes(env, secretKey), std::nullopt); + + jclass userClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile"); + jmethodID constructor = env->GetMethodID(userClass, "", "(J)V"); + jobject newConfig = env->NewObject(userClass, constructor, reinterpret_cast(profile)); + + return newConfig; +} + +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_UserProfile_setName( + JNIEnv* env, + jobject thiz, + jstring newName) { + auto profile = ptrToProfile(env, thiz); + profile->set_name(env->GetStringUTFChars(newName, nullptr)); +} + +JNIEXPORT jstring JNICALL +Java_network_loki_messenger_libsession_1util_UserProfile_getName(JNIEnv *env, jobject thiz) { + auto profile = ptrToProfile(env, thiz); + auto name = profile->get_name(); + if (name == std::nullopt) return nullptr; + jstring returnString = env->NewStringUTF(name->data()); + return returnString; +} + +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_UserProfile_free(JNIEnv *env, jobject thiz) { + auto profile = ptrToProfile(env, thiz); + delete profile; +} + +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_UserProfile_getPic(JNIEnv *env, jobject thiz) { + auto profile = ptrToProfile(env, thiz); + auto pic = profile->get_profile_pic(); + + jobject returnObject = util::serialize_user_pic(env, pic); + + return returnObject; +} + +JNIEXPORT void JNICALL +Java_network_loki_messenger_libsession_1util_UserProfile_setPic(JNIEnv *env, jobject thiz, + jobject user_pic) { + auto profile = ptrToProfile(env, thiz); + auto pic = util::deserialize_user_pic(env, user_pic); + auto url = env->GetStringUTFChars(pic.first, nullptr); + auto key = util::ustring_from_bytes(env, pic.second); + profile->set_profile_pic(url, key); +} + +} \ No newline at end of file diff --git a/libsession-util/src/main/cpp/user_profile.h b/libsession-util/src/main/cpp/user_profile.h new file mode 100644 index 0000000000..cb1b8d973b --- /dev/null +++ b/libsession-util/src/main/cpp/user_profile.h @@ -0,0 +1,14 @@ +#ifndef SESSION_ANDROID_USER_PROFILE_H +#define SESSION_ANDROID_USER_PROFILE_H + +#include "session/config/user_profile.hpp" +#include +#include + +inline session::config::UserProfile* ptrToProfile(JNIEnv* env, jobject obj) { + jclass configClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile"); + jfieldID pointerField = env->GetFieldID(configClass, "pointer", "J"); + return (session::config::UserProfile*) env->GetLongField(obj, pointerField); +} + +#endif \ No newline at end of file diff --git a/libsession-util/src/main/cpp/util.cpp b/libsession-util/src/main/cpp/util.cpp new file mode 100644 index 0000000000..d4cfee8cc4 --- /dev/null +++ b/libsession-util/src/main/cpp/util.cpp @@ -0,0 +1,60 @@ +#include "util.h" +#include +#include + +namespace util { + jbyteArray bytes_from_ustring(JNIEnv* env, session::ustring_view from_str) { + size_t length = from_str.length(); + auto jlength = (jsize)length; + jbyteArray new_array = env->NewByteArray(jlength); + env->SetByteArrayRegion(new_array, 0, jlength, (jbyte*)from_str.data()); + return new_array; + } + + session::ustring ustring_from_bytes(JNIEnv* env, jbyteArray byteArray) { + size_t len = env->GetArrayLength(byteArray); + auto bytes = env->GetByteArrayElements(byteArray, nullptr); + + session::ustring st{reinterpret_cast(bytes), len}; + env->ReleaseByteArrayElements(byteArray, bytes, 0); + return st; + } + + jobject serialize_user_pic(JNIEnv *env, std::optional pic) { + if (!pic) return nullptr; + + jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/UserPic"); + jmethodID constructor = env->GetMethodID(returnObjectClass, "", "(Ljava/lang/String;[B)V"); + jstring url = env->NewStringUTF(pic->url.data()); + jbyteArray byteArray = util::bytes_from_ustring(env, pic->key); + return env->NewObject(returnObjectClass, constructor, url, byteArray); + } + + std::pair deserialize_user_pic(JNIEnv *env, jobject user_pic) { + jclass userPicClass = env->FindClass("network/loki/messenger/libsession_util/util/UserPic"); + jfieldID picField = env->GetFieldID(userPicClass, "url", "Ljava/lang/String;"); + jfieldID keyField = env->GetFieldID(userPicClass, "key", "[B"); + auto pic = (jstring)env->GetObjectField(user_pic, picField); + auto key = (jbyteArray)env->GetObjectField(user_pic, keyField); + return {pic, key}; + } + +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_network_loki_messenger_libsession_1util_util_Sodium_ed25519KeyPair(JNIEnv *env, jobject thiz, jbyteArray seed) { + std::array ed_pk; + std::array ed_sk; + auto seed_bytes = util::ustring_from_bytes(env, seed); + crypto_sign_ed25519_seed_keypair(ed_pk.data(), ed_sk.data(), seed_bytes.data()); + + jclass kp_class = env->FindClass("network/loki/messenger/libsession_util/util/KeyPair"); + jmethodID kp_constructor = env->GetMethodID(kp_class, "", "([B[B)V"); + + jbyteArray pk_jarray = util::bytes_from_ustring(env, session::ustring_view {ed_pk.data(), ed_pk.size()}); + jbyteArray sk_jarray = util::bytes_from_ustring(env, session::ustring_view {ed_sk.data(), ed_sk.size()}); + + jobject return_obj = env->NewObject(kp_class, kp_constructor, pk_jarray, sk_jarray); + return return_obj; +} \ No newline at end of file diff --git a/libsession-util/src/main/cpp/util.h b/libsession-util/src/main/cpp/util.h new file mode 100644 index 0000000000..9050daa708 --- /dev/null +++ b/libsession-util/src/main/cpp/util.h @@ -0,0 +1,17 @@ +#ifndef SESSION_ANDROID_UTIL_H +#define SESSION_ANDROID_UTIL_H + +#include +#include +#include +#include "session/types.hpp" +#include "session/config/profile_pic.hpp" + +namespace util { + jbyteArray bytes_from_ustring(JNIEnv* env, session::ustring_view from_str); + session::ustring ustring_from_bytes(JNIEnv* env, jbyteArray byteArray); + jobject serialize_user_pic(JNIEnv *env, std::optional pic); + std::pair deserialize_user_pic(JNIEnv *env, jobject user_pic); +} + +#endif \ No newline at end of file diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt index e1069c598d..cf674f0a00 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt @@ -1,6 +1,7 @@ package network.loki.messenger.libsession_util import network.loki.messenger.libsession_util.util.ConfigWithSeqNo +import network.loki.messenger.libsession_util.util.Contact import network.loki.messenger.libsession_util.util.UserPic @@ -10,6 +11,7 @@ sealed class ConfigBase(protected val /* yucky */ pointer: Long) { System.loadLibrary("session_util") } } + external fun dirty(): Boolean external fun needsPush(): Boolean external fun needsDump(): Boolean @@ -18,18 +20,28 @@ sealed class ConfigBase(protected val /* yucky */ pointer: Long) { external fun encryptionDomain(): String external fun confirmPushed(seqNo: Long) external fun merge(toMerge: Array): Int + // Singular merge external fun merge(toMerge: ByteArray): Int } -class UserProfile(pointer: Long): ConfigBase(pointer) { +class Contacts(pointer: Long) : ConfigBase(pointer) { + external fun get(sessionId: String): Contact? + external fun getOrCreate(sessionId: String): Contact + external fun set(contact: Contact) + external fun erase(sessionId: String): Boolean +} + +class UserProfile(pointer: Long) : ConfigBase(pointer) { companion object { init { System.loadLibrary("session_util") } + external fun newInstance(ed25519SecretKey: ByteArray): UserProfile external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): UserProfile } + external fun setName(newName: String) external fun getName(): String? external fun free() diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Contact.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Contact.kt new file mode 100644 index 0000000000..5497dd9817 --- /dev/null +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Contact.kt @@ -0,0 +1,11 @@ +package network.loki.messenger.libsession_util.util + +data class Contact( + val id: String, + val name: String, + val nickname: String, + val approved: Boolean, + val approvedMe: Boolean, + val blocked: Boolean, + val profilePicture: UserPic +) \ No newline at end of file