feat: add group info

This commit is contained in:
0x330a
2023-09-01 16:14:04 +10:00
parent 3fe2250469
commit 84ebe44936
6 changed files with 47 additions and 11 deletions

View File

@@ -261,7 +261,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
val convo = when { val convo = when {
// recipient closed group // recipient closed group
recipient.isLegacyClosedGroupRecipient -> config.getOrConstructLegacyGroup(GroupUtil.doubleDecodeGroupId(recipient.address.serialize())) recipient.isLegacyClosedGroupRecipient -> config.getOrConstructLegacyGroup(GroupUtil.doubleDecodeGroupId(recipient.address.serialize()))
recipient.isClosedGroupRecipient -> config.getOrConstructGroup(recipient.address.serialize()) recipient.isClosedGroupRecipient -> config.getOrConstructClosedGroup(recipient.address.serialize())
// recipient is open group // recipient is open group
recipient.isOpenGroupRecipient -> { recipient.isOpenGroupRecipient -> {
val openGroupJoinUrl = getOpenGroup(threadId)?.joinURL ?: return val openGroupJoinUrl = getOpenGroup(threadId)?.joinURL ?: return
@@ -528,6 +528,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
is Conversation.OneToOne -> getThreadIdFor(conversation.sessionId, null, null, createThread = false) is Conversation.OneToOne -> getThreadIdFor(conversation.sessionId, null, null, createThread = false)
is Conversation.LegacyGroup -> getThreadIdFor("", conversation.groupId,null, createThread = false) is Conversation.LegacyGroup -> getThreadIdFor("", conversation.groupId,null, createThread = false)
is Conversation.Community -> getThreadIdFor("",null, "${conversation.baseCommunityInfo.baseUrl.removeSuffix("/")}.${conversation.baseCommunityInfo.room}", createThread = false) is Conversation.Community -> getThreadIdFor("",null, "${conversation.baseCommunityInfo.baseUrl.removeSuffix("/")}.${conversation.baseCommunityInfo.room}", createThread = false)
is Conversation.ClosedGroup -> getThreadIdFor(conversation.sessionId, null, null, createThread = false)
} }
if (threadId != null) { if (threadId != null) {
if (conversation.lastRead > getLastSeen(threadId)) { if (conversation.lastRead > getLastSeen(threadId)) {
@@ -872,7 +873,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
groupVolatileConfig.lastRead = formationTimestamp groupVolatileConfig.lastRead = formationTimestamp
volatiles.set(groupVolatileConfig) volatiles.set(groupVolatileConfig)
val groupInfo = GroupInfo.LegacyGroupInfo( val groupInfo = GroupInfo.LegacyGroupInfo(
sessionId = groupPublicKey, sessionId = SessionId.from(groupPublicKey),
name = name, name = name,
members = members, members = members,
priority = PRIORITY_VISIBLE, priority = PRIORITY_VISIBLE,
@@ -965,9 +966,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
} }
override fun isClosedGroup(publicKey: String): Boolean { override fun isClosedGroup(publicKey: String): Boolean {
val isClosedGroup = DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(publicKey) return DatabaseComponent.get(context).lokiAPIDatabase().isClosedGroup(publicKey)
val address = fromSerialized(publicKey)
return address.isClosedGroup || isClosedGroup
} }
override fun getClosedGroupEncryptionKeyPairs(groupPublicKey: String): MutableList<ECKeyPair> { override fun getClosedGroupEncryptionKeyPairs(groupPublicKey: String): MutableList<ECKeyPair> {
@@ -1313,7 +1312,7 @@ open class Storage(context: Context, helper: SQLCipherOpenHelper, private val co
groups.set(newGroupInfo) groups.set(newGroupInfo)
} }
threadRecipient.isClosedGroupRecipient -> { threadRecipient.isClosedGroupRecipient -> {
val newGroupInfo = groups.getGroupInfo(threadRecipient.address.serialize()).copy ( val newGroupInfo = groups.getOrConstructClosedGroup(threadRecipient.address.serialize()).copy (
priority = if (isPinned) PRIORITY_PINNED else PRIORITY_VISIBLE priority = if (isPinned) PRIORITY_PINNED else PRIORITY_VISIBLE
) )
groups.set(newGroupInfo) groups.set(newGroupInfo)

View File

@@ -560,6 +560,7 @@ class InstrumentedTests {
is Conversation.OneToOne -> seen.add("1-to-1: ${convo.sessionId}") is Conversation.OneToOne -> seen.add("1-to-1: ${convo.sessionId}")
is Conversation.Community -> seen.add("og: ${convo.baseCommunityInfo.baseUrl}/r/${convo.baseCommunityInfo.room}") is Conversation.Community -> seen.add("og: ${convo.baseCommunityInfo.baseUrl}/r/${convo.baseCommunityInfo.room}")
is Conversation.LegacyGroup -> seen.add("cl: ${convo.groupId}") is Conversation.LegacyGroup -> seen.add("cl: ${convo.groupId}")
is Conversation.ClosedGroup -> TODO()
} }
} }

View File

@@ -371,12 +371,20 @@ extern "C"
JNIEXPORT jobject JNICALL JNIEXPORT jobject JNICALL
Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructClosedGroup( Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_getOrConstructClosedGroup(
JNIEnv *env, jobject thiz, jstring session_id) { JNIEnv *env, jobject thiz, jstring session_id) {
// TODO: implement getOrConstructClosedGroup() 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);
return serialize_closed_group(env, group);
} }
extern "C" extern "C"
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseClosedGroup( Java_network_loki_messenger_libsession_1util_ConversationVolatileConfig_eraseClosedGroup(
JNIEnv *env, jobject thiz, jstring session_id) { JNIEnv *env, jobject thiz, jstring session_id) {
// TODO: implement eraseClosedGroup() 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;
} }

View File

@@ -58,6 +58,8 @@ inline jobject serialize_any(JNIEnv *env, session::config::convo::any any) {
return serialize_open_group(env, *og); return serialize_open_group(env, *og);
} else if (auto* lgc = std::get_if<session::config::convo::legacy_group>(&any)) { } else if (auto* lgc = std::get_if<session::config::convo::legacy_group>(&any)) {
return serialize_legacy_group(env, *lgc); return serialize_legacy_group(env, *lgc);
} else if (auto* gc = std::get_if<session::config::convo::group>(&any)) {
return serialize_closed_group(env, *gc);
} }
return nullptr; return nullptr;
} }
@@ -113,10 +115,30 @@ inline session::config::convo::legacy_group deserialize_legacy_closed_group(JNIE
return deserialized; return deserialized;
} }
inline session::config::convo::group deserialize_closed_group(JNIEnv* env, jobject info, session::config::ConvoInfoVolatile* conf) {
auto clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$ClosedGroup");
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");
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<session::config::convo::any> deserialize_any(JNIEnv *env, jobject convo, session::config::ConvoInfoVolatile *conf) { inline std::optional<session::config::convo::any> deserialize_any(JNIEnv *env, jobject convo, session::config::ConvoInfoVolatile *conf) {
auto oto_class = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne"); auto oto_class = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne");
auto og_class = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$Community"); auto og_class = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$Community");
auto lgc_class = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyGroup"); auto lgc_class = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$LegacyGroup");
auto gc_class = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$ClosedGroup");
auto object_class = env->GetObjectClass(convo); auto object_class = env->GetObjectClass(convo);
if (env->IsSameObject(object_class, oto_class)) { if (env->IsSameObject(object_class, oto_class)) {
return session::config::convo::any{deserialize_one_to_one(env, convo, conf)}; return session::config::convo::any{deserialize_one_to_one(env, convo, conf)};
@@ -124,6 +146,8 @@ inline std::optional<session::config::convo::any> deserialize_any(JNIEnv *env, j
return session::config::convo::any{deserialize_community(env, convo, conf)}; return session::config::convo::any{deserialize_community(env, convo, conf)};
} else if (env->IsSameObject(object_class, lgc_class)) { } else if (env->IsSameObject(object_class, lgc_class)) {
return session::config::convo::any{deserialize_legacy_closed_group(env, convo, conf)}; return session::config::convo::any{deserialize_legacy_closed_group(env, convo, conf)};
} else if (env->IsSameObject(object_class, gc_class)) {
return session::config::convo::any{deserialize_closed_group(env, convo, conf)};
} }
return std::nullopt; return std::nullopt;
} }

View File

@@ -132,9 +132,9 @@ inline jobject serialize_closed_group_info(JNIEnv* env, session::config::group_i
jbyteArray auth_bytes = util::bytes_from_ustring(env, info.auth_data); jbyteArray auth_bytes = util::bytes_from_ustring(env, info.auth_data);
jclass group_info_class = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$ClosedGroupInfo"); jclass group_info_class = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$ClosedGroupInfo");
jmethodID constructor = env->GetMethodID(group_info_class, "<init>", "(Lorg/session/libsignal/utilities/SessionId;[B[B)V"); jmethodID constructor = env->GetMethodID(group_info_class, "<init>", "(Lorg/session/libsignal/utilities/SessionId;[B[BJ)V");
jobject return_object = env->NewObject(group_info_class,constructor, jobject return_object = env->NewObject(group_info_class,constructor,
session_id, admin_bytes, auth_bytes); session_id, admin_bytes, auth_bytes, (jlong)info.priority);
return return_object; return return_object;
} }
@@ -143,6 +143,8 @@ inline session::config::group_info deserialize_closed_group_info(JNIEnv* env, jo
jfieldID id_field = env->GetFieldID(closed_group_class, "groupSessionId", "Lorg/session/libsignal/utilities/SessionId;"); jfieldID id_field = env->GetFieldID(closed_group_class, "groupSessionId", "Lorg/session/libsignal/utilities/SessionId;");
jfieldID secret_field = env->GetFieldID(closed_group_class, "adminKey", "[B"); jfieldID secret_field = env->GetFieldID(closed_group_class, "adminKey", "[B");
jfieldID auth_field = env->GetFieldID(closed_group_class, "authData", "[B"); jfieldID auth_field = env->GetFieldID(closed_group_class, "authData", "[B");
jfieldID priority_field = env->GetFieldID(closed_group_class, "priority", "J");
jobject id_jobject = env->GetObjectField(info_serialized, id_field); jobject id_jobject = env->GetObjectField(info_serialized, id_field);
jbyteArray secret_jBytes = (jbyteArray)env->GetObjectField(info_serialized, secret_field); jbyteArray secret_jBytes = (jbyteArray)env->GetObjectField(info_serialized, secret_field);
@@ -155,6 +157,7 @@ inline session::config::group_info deserialize_closed_group_info(JNIEnv* env, jo
session::config::group_info group_info(id_bytes); session::config::group_info group_info(id_bytes);
group_info.auth_data = auth_bytes; group_info.auth_data = auth_bytes;
group_info.secretkey = secret_bytes; group_info.secretkey = secret_bytes;
group_info.priority = env->GetLongField(info_serialized, priority_field);
return group_info; return group_info;
} }

View File

@@ -9,7 +9,8 @@ sealed class GroupInfo {
data class ClosedGroupInfo( data class ClosedGroupInfo(
val groupSessionId: SessionId, val groupSessionId: SessionId,
val adminKey: ByteArray, val adminKey: ByteArray,
val authData: ByteArray val authData: ByteArray,
val priority: Long,
): GroupInfo() { ): GroupInfo() {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true