mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-25 02:55:23 +00:00
feat: incorporate hashes from library, more wrapper for user groups and serialization from c++
This commit is contained in:
parent
c351cd6038
commit
858893a0e9
@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.database
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.content.contentValuesOf
|
import androidx.core.content.contentValuesOf
|
||||||
import androidx.core.database.getBlobOrNull
|
import androidx.core.database.getBlobOrNull
|
||||||
import androidx.core.database.getStringOrNull
|
|
||||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
||||||
|
|
||||||
class ConfigDatabase(context: Context, helper: SQLCipherOpenHelper): Database(context, helper) {
|
class ConfigDatabase(context: Context, helper: SQLCipherOpenHelper): Database(context, helper) {
|
||||||
@ -12,35 +11,32 @@ class ConfigDatabase(context: Context, helper: SQLCipherOpenHelper): Database(co
|
|||||||
private const val VARIANT = "variant"
|
private const val VARIANT = "variant"
|
||||||
private const val PUBKEY = "publicKey"
|
private const val PUBKEY = "publicKey"
|
||||||
private const val DATA = "data"
|
private const val DATA = "data"
|
||||||
private const val COMBINED_MESSAGE_HASHES = "combined_message_hashes"
|
|
||||||
|
|
||||||
private const val TABLE_NAME = "configs_table"
|
private const val TABLE_NAME = "configs_table"
|
||||||
|
|
||||||
const val CREATE_CONFIG_TABLE_COMMAND =
|
const val CREATE_CONFIG_TABLE_COMMAND =
|
||||||
"CREATE TABLE $TABLE_NAME ($VARIANT TEXT NOT NULL, $PUBKEY TEXT NOT NULL, $DATA BLOB, $COMBINED_MESSAGE_HASHES TEXT, PRIMARY KEY($VARIANT, $PUBKEY));"
|
"CREATE TABLE $TABLE_NAME ($VARIANT TEXT NOT NULL, $PUBKEY TEXT NOT NULL, $DATA BLOB, PRIMARY KEY($VARIANT, $PUBKEY));"
|
||||||
|
|
||||||
private const val VARIANT_AND_PUBKEY_WHERE = "$VARIANT = ? AND $PUBKEY = ?"
|
private const val VARIANT_AND_PUBKEY_WHERE = "$VARIANT = ? AND $PUBKEY = ?"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun storeConfig(variant: String, publicKey: String, data: ByteArray, hashes: List<String>) {
|
fun storeConfig(variant: String, publicKey: String, data: ByteArray) {
|
||||||
val db = writableDatabase
|
val db = writableDatabase
|
||||||
val contentValues = contentValuesOf(
|
val contentValues = contentValuesOf(
|
||||||
VARIANT to variant,
|
VARIANT to variant,
|
||||||
PUBKEY to publicKey,
|
PUBKEY to publicKey,
|
||||||
DATA to data,
|
DATA to data,
|
||||||
COMBINED_MESSAGE_HASHES to hashes.joinToString(",")
|
|
||||||
)
|
)
|
||||||
db.insertOrUpdate(TABLE_NAME, contentValues, VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey))
|
db.insertOrUpdate(TABLE_NAME, contentValues, VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun retrieveConfigAndHashes(variant: String, publicKey: String): Pair<ByteArray,List<String>>? {
|
fun retrieveConfigAndHashes(variant: String, publicKey: String): ByteArray? {
|
||||||
val db = readableDatabase
|
val db = readableDatabase
|
||||||
val query = db.query(TABLE_NAME, arrayOf(DATA, COMBINED_MESSAGE_HASHES), VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey),null, null, null)
|
val query = db.query(TABLE_NAME, arrayOf(DATA), VARIANT_AND_PUBKEY_WHERE, arrayOf(variant, publicKey),null, null, null)
|
||||||
return query?.use { cursor ->
|
return query?.use { cursor ->
|
||||||
if (!cursor.moveToFirst()) return@use null
|
if (!cursor.moveToFirst()) return@use null
|
||||||
val bytes = cursor.getBlobOrNull(cursor.getColumnIndex(DATA)) ?: return@use null
|
val bytes = cursor.getBlobOrNull(cursor.getColumnIndex(DATA)) ?: return@use null
|
||||||
val hashes = cursor.getStringOrNull(cursor.getColumnIndex(COMBINED_MESSAGE_HASHES))?.split(",") ?: emptyList()
|
bytes
|
||||||
bytes to hashes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +47,7 @@ class ConfigFactory(private val context: Context,
|
|||||||
Log.d("Loki-DBG", "Getting user configs and hashes")
|
Log.d("Loki-DBG", "Getting user configs and hashes")
|
||||||
val userDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.USER_PROFILE.name, publicKey)
|
val userDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.USER_PROFILE.name, publicKey)
|
||||||
_userConfig = if (userDump != null) {
|
_userConfig = if (userDump != null) {
|
||||||
val (bytes, hashes) = userDump
|
UserProfile.newInstance(secretKey, userDump)
|
||||||
userHashes.clear()
|
|
||||||
userHashes.addAll(hashes)
|
|
||||||
UserProfile.newInstance(secretKey, bytes)
|
|
||||||
} else {
|
} else {
|
||||||
UserProfile.newInstance(secretKey)
|
UserProfile.newInstance(secretKey)
|
||||||
}
|
}
|
||||||
@ -63,10 +60,7 @@ class ConfigFactory(private val context: Context,
|
|||||||
val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null
|
val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null
|
||||||
val contactsDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.CONTACTS.name, publicKey)
|
val contactsDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.CONTACTS.name, publicKey)
|
||||||
_contacts = if (contactsDump != null) {
|
_contacts = if (contactsDump != null) {
|
||||||
val (bytes, hashes) = contactsDump
|
Contacts.newInstance(secretKey, contactsDump)
|
||||||
contactsHashes.clear()
|
|
||||||
contactsHashes.addAll(hashes)
|
|
||||||
Contacts.newInstance(secretKey, bytes)
|
|
||||||
} else {
|
} else {
|
||||||
Contacts.newInstance(secretKey)
|
Contacts.newInstance(secretKey)
|
||||||
}
|
}
|
||||||
@ -79,10 +73,7 @@ class ConfigFactory(private val context: Context,
|
|||||||
val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null
|
val (secretKey, publicKey) = maybeGetUserInfo() ?: return@synchronized null
|
||||||
val convoDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey)
|
val convoDump = configDatabase.retrieveConfigAndHashes(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey)
|
||||||
_convoVolatileConfig = if (convoDump != null) {
|
_convoVolatileConfig = if (convoDump != null) {
|
||||||
val (bytes, hashes) = convoDump
|
ConversationVolatileConfig.newInstance(secretKey, convoDump)
|
||||||
convoHashes.clear()
|
|
||||||
convoHashes.addAll(hashes)
|
|
||||||
ConversationVolatileConfig.newInstance(secretKey, bytes)
|
|
||||||
} else {
|
} else {
|
||||||
ConversationVolatileConfig.newInstance(secretKey)
|
ConversationVolatileConfig.newInstance(secretKey)
|
||||||
}
|
}
|
||||||
@ -94,19 +85,19 @@ class ConfigFactory(private val context: Context,
|
|||||||
private fun persistUserConfigDump() = synchronized(userLock) {
|
private fun persistUserConfigDump() = synchronized(userLock) {
|
||||||
val dumped = user?.dump() ?: return
|
val dumped = user?.dump() ?: return
|
||||||
val (_, publicKey) = maybeGetUserInfo() ?: return
|
val (_, publicKey) = maybeGetUserInfo() ?: return
|
||||||
configDatabase.storeConfig(SharedConfigMessage.Kind.USER_PROFILE.name, publicKey, dumped, userHashes.toList())
|
configDatabase.storeConfig(SharedConfigMessage.Kind.USER_PROFILE.name, publicKey, dumped)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun persistContactsConfigDump() = synchronized(contactsLock) {
|
private fun persistContactsConfigDump() = synchronized(contactsLock) {
|
||||||
val dumped = contacts?.dump() ?: return
|
val dumped = contacts?.dump() ?: return
|
||||||
val (_, publicKey) = maybeGetUserInfo() ?: return
|
val (_, publicKey) = maybeGetUserInfo() ?: return
|
||||||
configDatabase.storeConfig(SharedConfigMessage.Kind.CONTACTS.name, publicKey, dumped, contactsHashes.toList())
|
configDatabase.storeConfig(SharedConfigMessage.Kind.CONTACTS.name, publicKey, dumped)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun persistConvoVolatileConfigDump() = synchronized (convoVolatileLock) {
|
private fun persistConvoVolatileConfigDump() = synchronized (convoVolatileLock) {
|
||||||
val dumped = convoVolatile?.dump() ?: return
|
val dumped = convoVolatile?.dump() ?: return
|
||||||
val (_, publicKey) = maybeGetUserInfo() ?: return
|
val (_, publicKey) = maybeGetUserInfo() ?: return
|
||||||
configDatabase.storeConfig(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey, dumped, convoHashes.toList())
|
configDatabase.storeConfig(SharedConfigMessage.Kind.CONVO_INFO_VOLATILE.name, publicKey, dumped)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun persist(forConfigObject: ConfigBase) {
|
override fun persist(forConfigObject: ConfigBase) {
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import network.loki.messenger.libsession_util.util.UserPic
|
import network.loki.messenger.libsession_util.util.UserPic
|
||||||
import org.session.libsession.messaging.contacts.Contact
|
import org.session.libsession.messaging.contacts.Contact
|
||||||
import org.session.libsession.utilities.SSKEnvironment
|
import org.session.libsession.utilities.SSKEnvironment
|
||||||
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
||||||
@ -84,6 +85,7 @@ class ProfileManager(private val context: Context, private val configFactory: Co
|
|||||||
|
|
||||||
override fun contactUpdatedInternal(contact: Contact) {
|
override fun contactUpdatedInternal(contact: Contact) {
|
||||||
val contactConfig = configFactory.contacts ?: return
|
val contactConfig = configFactory.contacts ?: return
|
||||||
|
if (contact.sessionID == TextSecurePreferences.getLocalNumber(context)) return
|
||||||
contactConfig.upsertContact(contact.sessionID) {
|
contactConfig.upsertContact(contact.sessionID) {
|
||||||
this.name = contact.name.orEmpty()
|
this.name = contact.name.orEmpty()
|
||||||
this.nickname = contact.nickname.orEmpty()
|
this.nickname = contact.nickname.orEmpty()
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit c76d7e06f6c1c258fe930bcd8d567b3bd4067262
|
Subproject commit 5a7569861d1b39d866ba7d8c7440db1908e84798
|
@ -120,29 +120,18 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_00024Companion_kindFor(J
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_network_loki_messenger_libsession_1util_ConfigBase_removeObsoleteHashes(JNIEnv *env,
|
|
||||||
jobject thiz,
|
|
||||||
jobjectArray to_remove) {
|
|
||||||
auto conf = ptrToConfigBase(env, thiz);
|
|
||||||
size_t number = env->GetArrayLength(to_remove);
|
|
||||||
for (int i = 0; i < number; i++) {
|
|
||||||
auto jElement = (jstring) env->GetObjectArrayElement(to_remove, i);
|
|
||||||
auto element_as_string = env->GetStringUTFChars(jElement, nullptr);
|
|
||||||
// TODO: uncomment when this is re-implemented
|
|
||||||
// conf->confirm_removed(element_as_string);
|
|
||||||
env->ReleaseStringUTFChars(jElement, element_as_string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_network_loki_messenger_libsession_1util_ConfigBase_obsoleteHashes(JNIEnv *env, jobject thiz) {
|
Java_network_loki_messenger_libsession_1util_ConfigBase_currentHashes(JNIEnv *env, jobject thiz) {
|
||||||
auto conf = ptrToConfigBase(env, thiz);
|
auto conf = ptrToConfigBase(env, thiz);
|
||||||
jclass stack = env->FindClass("java/util/Stack");
|
jclass stack = env->FindClass("java/util/Stack");
|
||||||
jmethodID init = env->GetMethodID(stack, "<init>", "()V");
|
jmethodID init = env->GetMethodID(stack, "<init>", "()V");
|
||||||
jobject our_stack = env->NewObject(stack, init);
|
jobject our_stack = env->NewObject(stack, init);
|
||||||
jmethodID push = env->GetMethodID(stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
jmethodID push = env->GetMethodID(stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
// TODO: implement obsoleteHashes()
|
auto vec = conf->current_hashes();
|
||||||
|
for (std::string element: vec) {
|
||||||
|
env->CallObjectMethod(our_stack, push, env->NewStringUTF(element.data()));
|
||||||
|
}
|
||||||
return our_stack;
|
return our_stack;
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ inline session::config::Contacts *ptrToContacts(JNIEnv *env, jobject obj) {
|
|||||||
inline jobject serialize_contact(JNIEnv *env, session::config::contact_info info) {
|
inline jobject serialize_contact(JNIEnv *env, session::config::contact_info info) {
|
||||||
jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact");
|
jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact");
|
||||||
jmethodID constructor = env->GetMethodID(contactClass, "<init>",
|
jmethodID constructor = env->GetMethodID(contactClass, "<init>",
|
||||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZLnetwork/loki/messenger/libsession_util/util/UserPic;)V");
|
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZLnetwork/loki/messenger/libsession_util/util/UserPic;I)V");
|
||||||
jstring id = env->NewStringUTF(info.session_id.data());
|
jstring id = env->NewStringUTF(info.session_id.data());
|
||||||
jstring name = env->NewStringUTF(info.name.data());
|
jstring name = env->NewStringUTF(info.name.data());
|
||||||
jstring nickname = env->NewStringUTF(info.nickname.data());
|
jstring nickname = env->NewStringUTF(info.nickname.data());
|
||||||
@ -23,14 +23,14 @@ inline jobject serialize_contact(JNIEnv *env, session::config::contact_info info
|
|||||||
approvedMe = info.approved_me;
|
approvedMe = info.approved_me;
|
||||||
blocked = info.blocked;
|
blocked = info.blocked;
|
||||||
jobject profilePic = util::serialize_user_pic(env, info.profile_picture);
|
jobject profilePic = util::serialize_user_pic(env, info.profile_picture);
|
||||||
jobject returnObj = env->NewObject(contactClass, constructor, id, name, nickname, approved, approvedMe, blocked, profilePic);
|
jobject returnObj = env->NewObject(contactClass, constructor, id, name, nickname, approved, approvedMe, blocked, profilePic, info.priority);
|
||||||
return returnObj;
|
return returnObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline session::config::contact_info* deserialize_contact(JNIEnv *env, jobject info) {
|
inline session::config::contact_info* deserialize_contact(JNIEnv *env, jobject info) {
|
||||||
jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact");
|
jclass contactClass = env->FindClass("network/loki/messenger/libsession_util/util/Contact");
|
||||||
|
|
||||||
jfieldID getId, getName, getNick, getApproved, getApprovedMe, getBlocked, getUserPic;
|
jfieldID getId, getName, getNick, getApproved, getApprovedMe, getBlocked, getUserPic, getPriority;
|
||||||
getId = env->GetFieldID(contactClass, "id", "Ljava/lang/String;");
|
getId = env->GetFieldID(contactClass, "id", "Ljava/lang/String;");
|
||||||
getName = env->GetFieldID(contactClass, "name", "Ljava/lang/String;");
|
getName = env->GetFieldID(contactClass, "name", "Ljava/lang/String;");
|
||||||
getNick = env->GetFieldID(contactClass, "nickname", "Ljava/lang/String;");
|
getNick = env->GetFieldID(contactClass, "nickname", "Ljava/lang/String;");
|
||||||
@ -38,11 +38,13 @@ inline session::config::contact_info* deserialize_contact(JNIEnv *env, jobject i
|
|||||||
getApprovedMe = env->GetFieldID(contactClass, "approvedMe", "Z");
|
getApprovedMe = env->GetFieldID(contactClass, "approvedMe", "Z");
|
||||||
getBlocked = env->GetFieldID(contactClass, "blocked", "Z");
|
getBlocked = env->GetFieldID(contactClass, "blocked", "Z");
|
||||||
getUserPic = env->GetFieldID(contactClass, "profilePicture", "Lnetwork/loki/messenger/libsession_util/util/UserPic;");
|
getUserPic = env->GetFieldID(contactClass, "profilePicture", "Lnetwork/loki/messenger/libsession_util/util/UserPic;");
|
||||||
|
getPriority = env->GetFieldID(contactClass, "priority", "I");
|
||||||
jstring name, nickname, session_id;
|
jstring name, nickname, session_id;
|
||||||
session_id = static_cast<jstring>(env->GetObjectField(info, getId));
|
session_id = static_cast<jstring>(env->GetObjectField(info, getId));
|
||||||
name = static_cast<jstring>(env->GetObjectField(info, getName));
|
name = static_cast<jstring>(env->GetObjectField(info, getName));
|
||||||
nickname = static_cast<jstring>(env->GetObjectField(info, getNick));
|
nickname = static_cast<jstring>(env->GetObjectField(info, getNick));
|
||||||
bool approved, approvedMe, blocked;
|
bool approved, approvedMe, blocked;
|
||||||
|
int priority = env->GetIntField(info, getPriority);
|
||||||
approved = env->GetBooleanField(info, getApproved);
|
approved = env->GetBooleanField(info, getApproved);
|
||||||
approvedMe = env->GetBooleanField(info, getApprovedMe);
|
approvedMe = env->GetBooleanField(info, getApprovedMe);
|
||||||
blocked = env->GetBooleanField(info, getBlocked);
|
blocked = env->GetBooleanField(info, getBlocked);
|
||||||
@ -86,6 +88,8 @@ inline session::config::contact_info* deserialize_contact(JNIEnv *env, jobject i
|
|||||||
env->ReleaseStringUTFChars(nickname, nickname_bytes);
|
env->ReleaseStringUTFChars(nickname, nickname_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contact_info->priority = priority;
|
||||||
|
|
||||||
return contact_info;
|
return contact_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,6 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_00024Companion_new
|
|||||||
jmethodID constructor = env->GetMethodID(contactsClass, "<init>", "(J)V");
|
jmethodID constructor = env->GetMethodID(contactsClass, "<init>", "(J)V");
|
||||||
jobject newConfig = env->NewObject(contactsClass, constructor, reinterpret_cast<jlong>(user_groups));
|
jobject newConfig = env->NewObject(contactsClass, constructor, reinterpret_cast<jlong>(user_groups));
|
||||||
|
|
||||||
user_groups->get_or_construct_legacy_group()
|
|
||||||
|
|
||||||
return newConfig;
|
return newConfig;
|
||||||
}
|
}
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
@ -50,7 +48,21 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getCommunityInfo(J
|
|||||||
jobject thiz,
|
jobject thiz,
|
||||||
jstring base_url,
|
jstring base_url,
|
||||||
jstring room) {
|
jstring room) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (community) {
|
||||||
|
serialize_legacy_group_info()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: implement getCommunityInfo()
|
// TODO: implement getCommunityInfo()
|
||||||
|
env->ReleaseStringUTFChars(base_url, base_url_bytes);
|
||||||
|
env->ReleaseStringUTFChars(room, room_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "conversation.h"
|
||||||
#include "session/config/user_groups.hpp"
|
#include "session/config/user_groups.hpp"
|
||||||
|
|
||||||
inline session::config::UserGroups* ptrToUserGroups(JNIEnv *env, jobject obj) {
|
inline session::config::UserGroups* ptrToUserGroups(JNIEnv *env, jobject obj) {
|
||||||
@ -51,4 +52,11 @@ inline jobject serialize_members(JNIEnv *env, std::map<std::string, bool> member
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline jobject serialize_community_info(JNIEnv *env, session::config::community_info info) {
|
||||||
|
auto priority = info.priority;
|
||||||
|
auto open_group = session::config::community::parse_full_url(info.full_url());
|
||||||
|
auto serialized_community = serialize_open_group(env, (session::config::community) info);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif //SESSION_ANDROID_USER_GROUPS_H
|
#endif //SESSION_ANDROID_USER_GROUPS_H
|
||||||
|
@ -34,8 +34,7 @@ sealed class ConfigBase(protected val /* yucky */ pointer: Long) {
|
|||||||
external fun encryptionDomain(): String
|
external fun encryptionDomain(): String
|
||||||
external fun confirmPushed(seqNo: Long, newHash: String)
|
external fun confirmPushed(seqNo: Long, newHash: String)
|
||||||
external fun merge(toMerge: Array<Pair<String,ByteArray>>): Int
|
external fun merge(toMerge: Array<Pair<String,ByteArray>>): Int
|
||||||
external fun obsoleteHashes(): List<String>
|
external fun currentHashes(): List<String>
|
||||||
external fun removeObsoleteHashes(toRemove: Array<String>)
|
|
||||||
|
|
||||||
external fun configNamespace(): Int
|
external fun configNamespace(): Int
|
||||||
|
|
||||||
|
@ -7,5 +7,6 @@ data class Contact(
|
|||||||
var approved: Boolean = false,
|
var approved: Boolean = false,
|
||||||
var approvedMe: Boolean = false,
|
var approvedMe: Boolean = false,
|
||||||
var blocked: Boolean = false,
|
var blocked: Boolean = false,
|
||||||
var profilePicture: UserPic = UserPic.DEFAULT
|
var profilePicture: UserPic = UserPic.DEFAULT,
|
||||||
|
var priority: Int
|
||||||
)
|
)
|
@ -57,6 +57,15 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
|
|||||||
// don't run anything if we don't need to push anything
|
// don't run anything if we don't need to push anything
|
||||||
if (configsRequiringPush.isEmpty()) return delegate.handleJobSucceeded(this, dispatcherName)
|
if (configsRequiringPush.isEmpty()) return delegate.handleJobSucceeded(this, dispatcherName)
|
||||||
|
|
||||||
|
// need to get the current hashes before we call `push()`
|
||||||
|
val toDeleteRequest = configsRequiringPush.map { base ->
|
||||||
|
// accumulate by adding together
|
||||||
|
base.currentHashes()
|
||||||
|
}.reduce(List<String>::plus).let { toDeleteFromAllNamespaces ->
|
||||||
|
if (toDeleteFromAllNamespaces.isEmpty()) null
|
||||||
|
else SnodeAPI.buildAuthenticatedDeleteBatchInfo(destination.destinationPublicKey(), toDeleteFromAllNamespaces)
|
||||||
|
}
|
||||||
|
|
||||||
// allow null results here so the list index matches configsRequiringPush
|
// allow null results here so the list index matches configsRequiringPush
|
||||||
val batchObjects: List<Pair<SharedConfigurationMessage, SnodeAPI.SnodeBatchRequestInfo>?> = configsRequiringPush.map { config ->
|
val batchObjects: List<Pair<SharedConfigurationMessage, SnodeAPI.SnodeBatchRequestInfo>?> = configsRequiringPush.map { config ->
|
||||||
val (data, seqNo) = config.push()
|
val (data, seqNo) = config.push()
|
||||||
@ -72,14 +81,6 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
|
|||||||
message to authenticated // to keep track of seqNo for calling confirmPushed later
|
message to authenticated // to keep track of seqNo for calling confirmPushed later
|
||||||
}
|
}
|
||||||
|
|
||||||
val toDeleteRequest = configsRequiringPush.map { base ->
|
|
||||||
base.obsoleteHashes()
|
|
||||||
// accumulate by adding together
|
|
||||||
}.reduce(List<String>::plus).let { toDeleteFromAllNamespaces ->
|
|
||||||
if (toDeleteFromAllNamespaces.isEmpty()) null
|
|
||||||
else SnodeAPI.buildAuthenticatedDeleteBatchInfo(destination.destinationPublicKey(), toDeleteFromAllNamespaces)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (batchObjects.any { it == null }) {
|
if (batchObjects.any { it == null }) {
|
||||||
// stop running here, something like a signing error occurred
|
// stop running here, something like a signing error occurred
|
||||||
return delegate.handleJobFailedPermanently(this, dispatcherName, NullPointerException("One or more requests had a null batch request info"))
|
return delegate.handleJobFailedPermanently(this, dispatcherName, NullPointerException("One or more requests had a null batch request info"))
|
||||||
@ -137,8 +138,6 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
|
|||||||
// confirm pushed seqno
|
// confirm pushed seqno
|
||||||
val thisSeqNo = toPushMessage.seqNo
|
val thisSeqNo = toPushMessage.seqNo
|
||||||
config.confirmPushed(thisSeqNo, insertHash)
|
config.confirmPushed(thisSeqNo, insertHash)
|
||||||
// wipe any of the existing hashes which we deleted (they may or may not be in this namespace)
|
|
||||||
config.removeObsoleteHashes(deletedHashes.toTypedArray())
|
|
||||||
Log.d(TAG, "Successfully removed the deleted hashes from ${config.javaClass.simpleName}")
|
Log.d(TAG, "Successfully removed the deleted hashes from ${config.javaClass.simpleName}")
|
||||||
// dump and write config after successful
|
// dump and write config after successful
|
||||||
if (config.needsDump()) { // usually this will be true?
|
if (config.needsDump()) { // usually this will be true?
|
||||||
|
@ -137,7 +137,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti
|
|||||||
namespace,
|
namespace,
|
||||||
updateLatestHash = false,
|
updateLatestHash = false,
|
||||||
updateStoredHashes = false,
|
updateStoredHashes = false,
|
||||||
).filter { (_, hash) -> !forConfigObject.obsoleteHashes().contains(hash) }
|
).filter { (_, hash) -> !forConfigObject.currentHashes().contains(hash) }
|
||||||
|
|
||||||
if (messages.isEmpty()) {
|
if (messages.isEmpty()) {
|
||||||
// no new messages to process
|
// no new messages to process
|
||||||
|
Loading…
Reference in New Issue
Block a user