mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-25 11:05:25 +00:00
feat: add basic conversation info volatile types and implementations, start working on tests
This commit is contained in:
parent
ee35cadfc6
commit
9bc69f7d54
@ -3,6 +3,7 @@ package network.loki.messenger.libsession_util
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import network.loki.messenger.libsession_util.util.Contact
|
||||
import network.loki.messenger.libsession_util.util.Conversation
|
||||
import network.loki.messenger.libsession_util.util.KeyPair
|
||||
import network.loki.messenger.libsession_util.util.Sodium
|
||||
import network.loki.messenger.libsession_util.util.UserPic
|
||||
@ -329,4 +330,26 @@ class InstrumentedTests {
|
||||
userProfile.free()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun jni_remove_all_test() {
|
||||
val convos = ConversationVolatileConfig.newInstance(keyPair.secretKey)
|
||||
assertEquals(0 /* number removed */, convos.eraseAll { true /* 'erase' every item */ })
|
||||
|
||||
val definitelyRealId = "050000000000000000000000000000000000000000000000000000000000000000"
|
||||
val definitelyRealConvo = Conversation.OneToOne(definitelyRealId, System.currentTimeMillis(), false)
|
||||
convos.set(definitelyRealConvo)
|
||||
|
||||
val anotherDefinitelyReadId = "051111111111111111111111111111111111111111111111111111111111111111"
|
||||
val anotherDefinitelyRealConvo = Conversation.OneToOne(anotherDefinitelyReadId, System.currentTimeMillis(), false)
|
||||
convos.set(anotherDefinitelyRealConvo)
|
||||
|
||||
assertEquals(2, convos.sizeOneToOnes())
|
||||
|
||||
val numErased = convos.eraseAll { convo ->
|
||||
convo is Conversation.OneToOne && convo.sessionId == definitelyRealId
|
||||
}
|
||||
assertEquals(1, numErased)
|
||||
assertEquals(1, convos.sizeOneToOnes())
|
||||
}
|
||||
|
||||
}
|
@ -7,13 +7,75 @@ extern "C"
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_00024Companion_newInstance___3B(
|
||||
JNIEnv *env, jobject thiz, jbyteArray ed25519_secret_key) {
|
||||
auto secret_key = util::ustring_from_bytes(env, ed25519_secret_key);
|
||||
auto* convo_info_volatile = new session::config::ConvoInfoVolatile(secret_key, std::nullopt);
|
||||
|
||||
jclass convoClass = env->FindClass("network/loki/messenger/libsession_util/ConversationVolatileConfig");
|
||||
jmethodID constructor = env->GetMethodID(convoClass, "<init>", "(J)V");
|
||||
jobject newConfig = env->NewObject(convoClass, constructor, reinterpret_cast<jlong>(convo_info_volatile));
|
||||
|
||||
return newConfig;
|
||||
}
|
||||
extern "C"
|
||||
#pragma ide diagnostic ignored "bugprone-reserved-identifier"
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_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* convo_info_volatile = new session::config::ConvoInfoVolatile(secret_key, initial);
|
||||
|
||||
jclass convoClass = env->FindClass("network/loki/messenger/libsession_util/ConversationVolatileConfig");
|
||||
jmethodID constructor = env->GetMethodID(convoClass, "<init>", "(J)V");
|
||||
jobject newConfig = env->NewObject(convoClass, constructor, reinterpret_cast<jlong>(convo_info_volatile));
|
||||
|
||||
return newConfig;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_set(JNIEnv *env,
|
||||
jobject thiz,
|
||||
jobject to_store) {
|
||||
auto conversations = ptrToConvoInfo(env, thiz);
|
||||
auto one_to_one = deserialize_one_to_one(env, to_store);
|
||||
conversations->set(*one_to_one);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_sizeOneToOnes(JNIEnv *env,
|
||||
jobject thiz) {
|
||||
auto conversations = ptrToConvoInfo(env, thiz);
|
||||
return conversations->size_1to1();
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseAll(JNIEnv *env,
|
||||
jobject thiz,
|
||||
jobject predicate) {
|
||||
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;");
|
||||
|
||||
jclass bool_class = env->FindClass("java/lang/Boolean");
|
||||
jfieldID bool_value = env->GetFieldID(bool_class, "value", "Z");
|
||||
|
||||
int removed = 0;
|
||||
|
||||
for (auto it = conversations->begin(); it != conversations->end(); ) {
|
||||
auto result = env->CallObjectMethod(predicate, predicate_call, serialize_any(env, *it));
|
||||
bool bool_result = env->GetBooleanField(result, bool_value);
|
||||
if (bool_result) {
|
||||
it = conversations->erase(it);
|
||||
removed++;
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
@ -5,28 +5,108 @@
|
||||
#include "util.h"
|
||||
#include "session/config/convo_info_volatile.hpp"
|
||||
|
||||
inline session::config::ConvoInfoVolatile *ptrToContacts(JNIEnv *env, jobject obj) {
|
||||
inline session::config::ConvoInfoVolatile *ptrToConvoInfo(JNIEnv *env, jobject obj) {
|
||||
jclass contactsClass = env->FindClass("network/loki/messenger/libsession_util/ConversationVolatileConfig");
|
||||
jfieldID pointerField = env->GetFieldID(contactsClass, "pointer", "J");
|
||||
return (session::config::ConvoInfoVolatile *) env->GetLongField(obj, pointerField);
|
||||
}
|
||||
|
||||
inline jobject serialize_one_on_one(JNIEnv *env, session::config::convo::one_to_one one_to_one) {
|
||||
// TODO serialize function
|
||||
inline jobject serialize_one_to_one(JNIEnv *env, session::config::convo::one_to_one *one_to_one) {
|
||||
jclass clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne");
|
||||
jmethodID constructor = env->GetMethodID(clazz, "<init>", "(Ljava/lang/String;JZ)V");
|
||||
auto session_id = 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, constructor, session_id, last_read, unread);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
inline jobject serialize_open_group(JNIEnv *env, session::config::convo::open_group open_group) {
|
||||
// TODO
|
||||
inline jobject serialize_open_group(JNIEnv *env, session::config::convo::open_group *open_group) {
|
||||
jclass clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OpenGroup");
|
||||
jmethodID constructor = env->GetMethodID(clazz, "<init>", "(Ljava/lang/String;Ljava/lang/String;[BJZ)V");
|
||||
auto base_url = env->NewStringUTF(open_group->base_url().data());
|
||||
auto room = env->NewStringUTF(open_group->room().data());
|
||||
auto pubkey_ustring = open_group->pubkey();
|
||||
auto pubkey_jarray = util::bytes_from_ustring(env, session::ustring_view {pubkey_ustring.data(), pubkey_ustring.size()});
|
||||
auto last_read = open_group->last_read;
|
||||
auto unread = open_group->unread;
|
||||
jobject serialized = env->NewObject(clazz, constructor, base_url, room, pubkey_jarray, last_read, unread);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
inline jobject serialize_legacy_group(JNIEnv *env, session::config::convo::legacy_closed_group legacy_group) {
|
||||
|
||||
inline jobject serialize_legacy_group(JNIEnv *env, session::config::convo::legacy_closed_group *legacy_group) {
|
||||
jclass clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyClosedGroup");
|
||||
jmethodID constructor = env->GetMethodID(clazz, "<init>", "(Ljava/lang/String;JZ)V");
|
||||
auto group_id = env->NewStringUTF(legacy_group->id.data());
|
||||
auto last_read = legacy_group->last_read;
|
||||
auto unread = legacy_group->unread;
|
||||
jobject serialized = env->NewObject(clazz, constructor, group_id, last_read, unread);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
inline jobject serialize_any(JNIEnv *env, session::config::convo::any)
|
||||
inline jobject serialize_any(JNIEnv *env, session::config::convo::any any) {
|
||||
if (auto* dm = std::get_if<session::config::convo::one_to_one>(&any)) {
|
||||
return serialize_one_to_one(env, dm);
|
||||
} else if (auto* og = std::get_if<session::config::convo::open_group>(&any)) {
|
||||
return serialize_open_group(env, og);
|
||||
} else if (auto* lgc = std::get_if<session::config::convo::legacy_closed_group>(&any)) {
|
||||
return serialize_legacy_group(env, lgc);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline session::config::ConvoInfoVolatile* deserialize_convo_info(JNIEnv *env, jobject info) {
|
||||
// TODO deserialize function
|
||||
inline session::config::convo::one_to_one* deserialize_one_to_one(JNIEnv *env, jobject info) {
|
||||
auto clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne");
|
||||
auto id_getter = env->GetFieldID(clazz, "sessionId", "Ljava/lang/String;");
|
||||
auto last_read_getter = env->GetFieldID(clazz, "lastRead", "J");
|
||||
auto unread_getter = env->GetFieldID(clazz, "unread", "Z");
|
||||
jstring id = static_cast<jstring>(env->GetObjectField(info, id_getter));
|
||||
auto id_chars = env->GetStringUTFChars(id, nullptr);
|
||||
std::string id_string = std::string{id_chars};
|
||||
auto deserialized = new session::config::convo::one_to_one(id_string);
|
||||
deserialized->last_read = env->GetLongField(info, last_read_getter);
|
||||
deserialized->unread = env->GetBooleanField(info, unread_getter);
|
||||
env->ReleaseStringUTFChars(id, id_chars);
|
||||
return deserialized;
|
||||
}
|
||||
|
||||
inline session::config::convo::open_group* deserialize_open_group(JNIEnv *env, jobject info) {
|
||||
auto clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OpenGroup");
|
||||
auto url_getter = env->GetFieldID(clazz, "baseUrl", "Ljava/lang/String;");
|
||||
auto room_getter = env->GetFieldID(clazz, "room", "Ljava/lang/String;");
|
||||
auto pub_key_getter = env->GetFieldID(clazz, "pubKey", "[B");
|
||||
auto last_read_getter = env->GetFieldID(clazz, "lastRead", "J");
|
||||
auto unread_getter = env->GetFieldID(clazz, "unread", "Z");
|
||||
jstring base_url = static_cast<jstring>(env->GetObjectField(info, url_getter));
|
||||
jstring room = static_cast<jstring>(env->GetObjectField(info, room_getter));
|
||||
jbyteArray pub_key = (jbyteArray)env->GetObjectField(info, pub_key_getter);
|
||||
auto base_bytes = env->GetStringUTFChars(base_url, nullptr);
|
||||
auto base_string = std::string {base_bytes};
|
||||
auto room_bytes = env->GetStringUTFChars(room, nullptr);
|
||||
auto room_string = std::string {room_bytes};
|
||||
auto pub_key_ustring = util::ustring_from_bytes(env, pub_key);
|
||||
|
||||
auto deserialized = new session::config::convo::open_group(base_string, room_string,pub_key_ustring);
|
||||
deserialized->last_read = env->GetLongField(info, last_read_getter);
|
||||
deserialized->unread = env->GetBooleanField(info, unread_getter);
|
||||
env->ReleaseStringUTFChars(base_url, base_bytes);
|
||||
env->ReleaseStringUTFChars(room, room_bytes);
|
||||
return deserialized;
|
||||
}
|
||||
|
||||
inline session::config::convo::legacy_closed_group* deserialize_legacy_closed_group(JNIEnv *env, jobject info) {
|
||||
auto clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyClosedGroup");
|
||||
auto group_id_getter = env->GetFieldID(clazz, "groupId", "Ljava/lang/String;");
|
||||
auto last_read_getter = env->GetFieldID(clazz, "lastRead", "J");
|
||||
auto unread_getter = env->GetFieldID(clazz, "unread", "Z");
|
||||
auto group_id = static_cast<jstring>(env->GetObjectField(info, group_id_getter));
|
||||
auto group_id_bytes = env->GetStringUTFChars(group_id, nullptr);
|
||||
auto group_id_string = std::string{group_id_bytes};
|
||||
auto deserialized = new session::config::convo::legacy_closed_group(group_id_string);
|
||||
deserialized->last_read = env->GetLongField(info, last_read_getter);
|
||||
deserialized->unread = env->GetBooleanField(info, unread_getter);
|
||||
env->ReleaseStringUTFChars(group_id, group_id_bytes);
|
||||
return deserialized;
|
||||
}
|
||||
|
||||
#endif //SESSION_ANDROID_CONVERSATION_H
|
@ -2,6 +2,7 @@ package network.loki.messenger.libsession_util
|
||||
|
||||
import network.loki.messenger.libsession_util.util.ConfigWithSeqNo
|
||||
import network.loki.messenger.libsession_util.util.Contact
|
||||
import network.loki.messenger.libsession_util.util.Conversation
|
||||
import network.loki.messenger.libsession_util.util.UserPic
|
||||
|
||||
|
||||
@ -56,7 +57,6 @@ class UserProfile(pointer: Long) : ConfigBase(pointer) {
|
||||
init {
|
||||
System.loadLibrary("session_util")
|
||||
}
|
||||
|
||||
external fun newInstance(ed25519SecretKey: ByteArray): UserProfile
|
||||
external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): UserProfile
|
||||
}
|
||||
@ -72,11 +72,31 @@ class ConversationVolatileConfig(pointer: Long): ConfigBase(pointer) {
|
||||
init {
|
||||
System.loadLibrary("session_util")
|
||||
}
|
||||
|
||||
external fun newInstance(ed25519SecretKey: ByteArray): ConversationVolatileConfig
|
||||
|
||||
external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): ConversationVolatileConfig
|
||||
|
||||
}
|
||||
|
||||
external fun getOneToOne(pubKeyHex: String): Conversation.OneToOne?
|
||||
external fun getOrConstructOneToOne(pubKeyHex: String): Conversation.OneToOne
|
||||
external fun set(toStore: Conversation.OneToOne)
|
||||
|
||||
external fun getOpenGroup(baseUrl: String, room: String, pubKeyHex: String): Conversation.OpenGroup?
|
||||
external fun getOrConstructOpenGroup(baseUrl: String, room: String, pubKey: ByteArray): Conversation.OpenGroup
|
||||
|
||||
external fun getLegacyClosedGroup(groupId: String): Conversation.LegacyClosedGroup?
|
||||
external fun getOrConstructLegacyClosedGroup(groupId: String): Conversation.LegacyClosedGroup
|
||||
|
||||
external fun erase(conversation: Conversation): Boolean
|
||||
|
||||
/**
|
||||
* Erase all conversations that do not satisfy the `predicate`, similar to [MutableList.removeAll]
|
||||
*/
|
||||
external fun eraseAll(predicate: (Conversation) -> Boolean): Int
|
||||
|
||||
external fun sizeOneToOnes(): Int
|
||||
external fun sizeOpenGroups(): Int
|
||||
external fun sizeLegacyClosedGroups(): Int
|
||||
|
||||
external fun all(): List<Conversation>
|
||||
|
||||
}
|
@ -1,17 +1,22 @@
|
||||
package network.loki.messenger.libsession_util.util
|
||||
|
||||
sealed class Conversation {
|
||||
|
||||
abstract val lastRead: Long
|
||||
abstract val unread: Boolean
|
||||
|
||||
data class OneToOne(
|
||||
val sessionId: String,
|
||||
val lastRead: Long,
|
||||
val expiryMode: ExpiryMode,
|
||||
override val lastRead: Long,
|
||||
override val unread: Boolean
|
||||
): Conversation()
|
||||
|
||||
data class OpenGroup(
|
||||
val baseUrl: String,
|
||||
val room: String,
|
||||
val room: String, // lowercase
|
||||
val pubKey: ByteArray,
|
||||
val lastRead: Long,
|
||||
override val lastRead: Long,
|
||||
override val unread: Boolean
|
||||
) : Conversation() {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
@ -38,7 +43,7 @@ sealed class Conversation {
|
||||
|
||||
data class LegacyClosedGroup(
|
||||
val groupId: String,
|
||||
val lastRead: Long,
|
||||
val expiryMode: ExpiryMode
|
||||
override val lastRead: Long,
|
||||
override val unread: Boolean
|
||||
): Conversation()
|
||||
}
|
Loading…
Reference in New Issue
Block a user