Skip to content

Commit

Permalink
conversation: move logic of message management in daemon
Browse files Browse the repository at this point in the history
This heavily changes the API for the client. The goal here is
to move the logic to construct the history to show in the daemon
and not the client. This has several advantages:

1. Logic is common across every platforms, so bugs should not be
platform-specific
2. Client got less logic
3. Signal are simplified, if an edition comes, "MessageUpdated"
will be triggered instead MessageReceived.
4. Some tests are added for linearizing the history.
5. Search on edition is fixed.

Tests got heavily re-written, but the content didn't change (2 tests
are added, the rest is simplification).

GitLab: #831
Change-Id: Ie7c81077067e9e49db1dd396829c9225c0512c16
  • Loading branch information
Sébastien Blin committed Dec 28, 2023
1 parent f83c60f commit 8468f15
Show file tree
Hide file tree
Showing 24 changed files with 2,779 additions and 5,482 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16)

project(jami-core
VERSION 13.11.0
VERSION 14.0.0
LANGUAGES C CXX)
set(PACKAGE_NAME "Jami Daemon")
set (CMAKE_CXX_STANDARD 17)
Expand Down
169 changes: 160 additions & 9 deletions bin/dbus/cx.ring.Ring.ConfigurationManager.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1848,9 +1848,21 @@
<arg type="u" name="id" direction="out"/>
</method>

<method name="loadConversationUntil" tp:name-for-bindings="loadConversationUntil">
<tp:added version="10.0.0"/>
<tp:docstring>
<method name="loadConversation" tp:name-for-bindings="loadConversation">
<tp:added version="14.0.0"/>
<tp:docstring>
Load messages from a conversation
</tp:docstring>
<arg type="s" name="accountId" direction="in"/>
<arg type="s" name="conversationId" direction="in"/>
<arg type="s" name="fromMessage" direction="in"/>
<arg type="u" name="n" direction="in"/>
<arg type="u" name="id" direction="out"/>
</method>

<method name="loadConversationUntil" tp:name-for-bindings="loadConversationUntil">
<tp:added version="10.0.0"/>
<tp:docstring>
Load messages from a conversation
</tp:docstring>
<arg type="s" name="accountId" direction="in"/>
Expand All @@ -1873,6 +1885,15 @@
<arg type="u" name="count" direction="out"/>
</method>

<method name="clearCache" tp:name-for-bindings="clearCache">
<tp:added version="14.0.0"/>
<tp:docstring>
Clear interactions loaded from daemon. Used by dbus to reload interactions
</tp:docstring>
<arg type="s" name="accountId" direction="in"/>
<arg type="s" name="conversationId" direction="in"/>
</method>

<method name="searchConversation" tp:name-for-bindings="searchConversation">
<tp:added version="13.4.0"/>
<tp:docstring>
Expand Down Expand Up @@ -1992,9 +2013,37 @@
</arg>
</signal>

<signal name="messagesFound" tp:name-for-bindings="messagesFound">
<tp:added version="10.0.0"/>
<tp:docstring>
<signal name="swarmLoaded" tp:name-for-bindings="swarmLoaded">
<tp:added version="14.0.0"/>
<tp:docstring>
Notify clients when a conversation is loaded
</tp:docstring>
<arg type="u" name="id">
<tp:docstring>
Id of the related loadConversationMessages's request
</tp:docstring>
</arg>
<arg type="s" name="account_id">
<tp:docstring>
Account id related
</tp:docstring>
</arg>
<arg type="s" name="conversation_id">
<tp:docstring>
Conversation id
</tp:docstring>
</arg>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out3" value="VectorSwarmMessage"/>
<arg type="a(sssa{ss}aa{ss}aa{ss})" name="messages">
<tp:docstring>
Messages of the conversation
</tp:docstring>
</arg>
</signal>

<signal name="messagesFound" tp:name-for-bindings="messagesFound">
<tp:added version="10.0.0"/>
<tp:docstring>
Notify clients when messages matching a regex are found
</tp:docstring>
<arg type="u" name="id">
Expand Down Expand Up @@ -2043,9 +2092,111 @@
</arg>
</signal>

<signal name="conversationProfileUpdated" tp:name-for-bindings="conversationProfileUpdated">
<tp:added version="13.4.0"/>
<tp:docstring>
<signal name="swarmMessageReceived" tp:name-for-bindings="swarmMessageReceived">
<tp:added version="14.0.0"/>
<tp:docstring>
Notify clients when a conversation receives a new message
</tp:docstring>
<arg type="s" name="account_id">
<tp:docstring>
Account id related
</tp:docstring>
</arg>
<arg type="s" name="conversation_id">
<tp:docstring>
Conversation id
</tp:docstring>
</arg>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out2" value="SwarmMessage"/>
<arg type="(sssa{ss}aa{ss}aa{ss})" name="message">
<tp:docstring>
The new message
</tp:docstring>
</arg>
</signal>

<signal name="swarmMessageUpdated" tp:name-for-bindings="swarmMessageUpdated">
<tp:added version="14.0.0"/>
<tp:docstring>
Notify clients when a conversation receives a new message
</tp:docstring>
<arg type="s" name="account_id">
<tp:docstring>
Account id related
</tp:docstring>
</arg>
<arg type="s" name="conversation_id">
<tp:docstring>
Conversation id
</tp:docstring>
</arg>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out2" value="SwarmMessage"/>
<arg type="(sssa{ss}aa{ss}aa{ss})" name="message">
<tp:docstring>
The new message
</tp:docstring>
</arg>
</signal>

<signal name="reactionAdded" tp:name-for-bindings="reactionAdded">
<tp:added version="14.0.0"/>
<tp:docstring>
Notify clients when a conversation receives a new message
</tp:docstring>
<arg type="s" name="account_id">
<tp:docstring>
Account id related
</tp:docstring>
</arg>
<arg type="s" name="conversation_id">
<tp:docstring>
Conversation id
</tp:docstring>
</arg>
<arg type="s" name="message_id">
<tp:docstring>
Conversation id
</tp:docstring>
</arg>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out3" value="MapStringString"/>
<arg type="a{ss}" name="reaction">
<tp:docstring>
The new message
</tp:docstring>
</arg>
</signal>

<signal name="reactionRemoved" tp:name-for-bindings="reactionRemoved">
<tp:added version="14.0.0"/>
<tp:docstring>
Notify clients when a conversation receives a new message
</tp:docstring>
<arg type="s" name="account_id">
<tp:docstring>
Account id related
</tp:docstring>
</arg>
<arg type="s" name="conversation_id">
<tp:docstring>
Conversation id
</tp:docstring>
</arg>
<arg type="s" name="message_id">
<tp:docstring>
Message's id
</tp:docstring>
</arg>
<arg type="s" name="reaction_id">
<tp:docstring>
Reaction's id
</tp:docstring>
</arg>
</signal>


<signal name="conversationProfileUpdated" tp:name-for-bindings="conversationProfileUpdated">
<tp:added version="13.4.0"/>
<tp:docstring>
Notify clients when a conversation got its profile changed.
</tp:docstring>
<arg type="s" name="account_id">
Expand Down
37 changes: 37 additions & 0 deletions bin/dbus/dbusconfigurationmanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
class DBusConfigurationManager : public sdbus::AdaptorInterfaces<cx::ring::Ring::ConfigurationManager_adaptor>
{
public:
using DBusSwarmMessage = sdbus::Struct<std::string, std::string, std::string, std::map<std::string, std::string>, std::vector<std::map<std::string, std::string>>, std::vector<std::map<std::string, std::string>>>;
DBusConfigurationManager(sdbus::IConnection& connection)
: AdaptorInterfaces(connection, "/cx/ring/Ring/ConfigurationManager")
{
Expand Down Expand Up @@ -931,6 +932,15 @@ class DBusConfigurationManager : public sdbus::AdaptorInterfaces<cx::ring::Ring:
return libjami::loadConversationMessages(accountId, conversationId, fromMessage, n);
}

uint32_t
loadConversation(const std::string& accountId,
const std::string& conversationId,
const std::string& fromMessage,
const uint32_t& n)
{
return libjami::loadConversation(accountId, conversationId, fromMessage, n);
}

uint32_t
loadConversationUntil(const std::string& accountId,
const std::string& conversationId,
Expand All @@ -950,6 +960,13 @@ class DBusConfigurationManager : public sdbus::AdaptorInterfaces<cx::ring::Ring:
return libjami::countInteractions(accountId, conversationId, toId, fromId, authorUri);
}

void
clearCache(const std::string& accountId,
const std::string& conversationId)
{
return libjami::clearCache(accountId, conversationId);
}

uint32_t
searchConversation(const std::string& accountId,
const std::string& conversationId,
Expand Down Expand Up @@ -1122,10 +1139,30 @@ class DBusConfigurationManager : public sdbus::AdaptorInterfaces<cx::ring::Ring:
const std::map<std::string, SharedCallback> convEvHandlers = {
exportable_serialized_callback<ConversationSignal::ConversationLoaded>(
std::bind(&DBusConfigurationManager::emitConversationLoaded, this, _1, _2, _3, _4)),
exportable_serialized_callback<ConversationSignal::SwarmLoaded>([this](const uint32_t& id, const std::string& account_id, const std::string& conversation_id, const std::vector<libjami::SwarmMessage>& messages) {
std::vector<DBusSwarmMessage> msgList;
for (const auto& message: messages) {
DBusSwarmMessage msg {message.id, message.type, message.linearizedParent, message.body, message.reactions, message.editions};
msgList.push_back(msg);
}
DBusConfigurationManager::emitSwarmLoaded(id, account_id, conversation_id, msgList);
}),
exportable_serialized_callback<ConversationSignal::MessagesFound>(
std::bind(&DBusConfigurationManager::emitMessagesFound, this, _1, _2, _3, _4)),
exportable_serialized_callback<ConversationSignal::MessageReceived>(
std::bind(&DBusConfigurationManager::emitMessageReceived, this, _1, _2, _3)),
exportable_serialized_callback<ConversationSignal::SwarmMessageReceived>([this](const std::string& account_id, const std::string& conversation_id, const libjami::SwarmMessage& message) {
DBusSwarmMessage msg {message.id, message.type, message.linearizedParent, message.body, message.reactions, message.editions};
DBusConfigurationManager::emitSwarmMessageReceived(account_id, conversation_id, msg);
}),
exportable_serialized_callback<ConversationSignal::SwarmMessageUpdated>([this](const std::string& account_id, const std::string& conversation_id, const libjami::SwarmMessage& message) {
DBusSwarmMessage msg {message.id, message.type, message.linearizedParent, message.body, message.reactions, message.editions};
DBusConfigurationManager::emitSwarmMessageUpdated(account_id, conversation_id, msg);
}),
exportable_serialized_callback<ConversationSignal::ReactionAdded>(
std::bind(&DBusConfigurationManager::emitReactionAdded, this, _1, _2, _3, _4)),
exportable_serialized_callback<ConversationSignal::ReactionRemoved>(
std::bind(&DBusConfigurationManager::emitReactionRemoved, this, _1, _2, _3, _4)),
exportable_serialized_callback<ConversationSignal::ConversationProfileUpdated>(
std::bind(&DBusConfigurationManager::emitConversationProfileUpdated, this, _1, _2, _3)),
exportable_serialized_callback<ConversationSignal::ConversationRequestReceived>(
Expand Down
22 changes: 22 additions & 0 deletions bin/jni/conversation.i
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@ class ConversationCallback {
public:
virtual ~ConversationCallback(){}
virtual void conversationLoaded(uint32_t /* id */, const std::string& /*accountId*/, const std::string& /* conversationId */, std::vector<std::map<std::string, std::string>> /*messages*/){}
virtual void swarmLoaded(uint32_t /* id */, const std::string& /*accountId*/, const std::string& /* conversationId */, std::vector<libjami::SwarmMessage> /*messages*/){}
virtual void messagesFound(uint32_t /* id */, const std::string& /*accountId*/, const std::string& /* conversationId */, std::vector<std::map<std::string, std::string>> /*messages*/){}
virtual void messageReceived(const std::string& /*accountId*/, const std::string& /* conversationId */, std::map<std::string, std::string> /*message*/){}
virtual void swarmMessageReceived(const std::string& /*accountId*/, const std::string& /* conversationId */, const libjami::SwarmMessage& /*message*/){}
virtual void swarmMessageUpdated(const std::string& /*accountId*/, const std::string& /* conversationId */, const libjami::SwarmMessage& /*message*/){}
virtual void reactionAdded(const std::string& /*accountId*/, const std::string& /* conversationId */, const std::string& /* messageId */, std::map<std::string, std::string> /*reaction*/){}
virtual void reactionRemoved(const std::string& /*accountId*/, const std::string& /* conversationId */, const std::string& /* messageId */, const std::string& /* reactionId */){}
virtual void conversationProfileUpdated(const std::string& /*accountId*/, const std::string& /* conversationId */, std::map<std::string, std::string> /*profile*/){}
virtual void conversationRequestReceived(const std::string& /*accountId*/, const std::string& /* conversationId */, std::map<std::string, std::string> /*metadatas*/){}
virtual void conversationRequestDeclined(const std::string& /*accountId*/, const std::string& /* conversationId */){}
Expand All @@ -43,6 +48,16 @@ public:

namespace libjami {

struct SwarmMessage
{
std::string id;
std::string type;
std::string linearizedParent;
std::map<std::string, std::string> body;
std::vector<std::map<std::string, std::string>> reactions;
std::vector<std::map<std::string, std::string>> editions;
};

// Conversation management
std::string startConversation(const std::string& accountId);
void acceptConversationRequest(const std::string& accountId, const std::string& conversationId);
Expand All @@ -64,8 +79,10 @@ namespace libjami {
// Message send/load
void sendMessage(const std::string& accountId, const std::string& conversationId, const std::string& message, const std::string& replyTo, const int32_t& flag);
uint32_t loadConversationMessages(const std::string& accountId, const std::string& conversationId, const std::string& fromMessage, size_t n);
uint32_t loadConversation(const std::string& accountId, const std::string& conversationId, const std::string& fromMessage, size_t n);
uint32_t loadConversationUntil(const std::string& accountId, const std::string& conversationId, const std::string& fromMessage, const std::string& toMessage);
uint32_t countInteractions(const std::string& accountId, const std::string& conversationId, const std::string& toId, const std::string& fromId, const std::string& authorUri);
void clearCache(const std::string& accountId, const std::string& conversationId);
uint32_t searchConversation(const std::string& accountId,
const std::string& conversationId,
const std::string& author,
Expand All @@ -82,8 +99,13 @@ class ConversationCallback {
public:
virtual ~ConversationCallback(){}
virtual void conversationLoaded(uint32_t /* id */, const std::string& /*accountId*/, const std::string& /* conversationId */, std::vector<std::map<std::string, std::string>> /*messages*/){}
virtual void swarmLoaded(uint32_t /* id */, const std::string& /*accountId*/, const std::string& /* conversationId */, std::vector<libjami::SwarmMessage> /*messages*/){}
virtual void messagesFound(uint32_t /* id */, const std::string& /*accountId*/, const std::string& /* conversationId */, std::vector<std::map<std::string, std::string>> /*messages*/){}
virtual void messageReceived(const std::string& /*accountId*/, const std::string& /* conversationId */, std::map<std::string, std::string> /*message*/){}
virtual void swarmMessageReceived(const std::string& /*accountId*/, const std::string& /* conversationId */, const libjami::SwarmMessage& /*message*/){}
virtual void swarmMessageUpdated(const std::string& /*accountId*/, const std::string& /* conversationId */, const libjami::SwarmMessage& /*message*/){}
virtual void reactionAdded(const std::string& /*accountId*/, const std::string& /* conversationId */, const std::string& /* messageId */, std::map<std::string, std::string> /*messageId*/){}
virtual void reactionRemoved(const std::string& /*accountId*/, const std::string& /* conversationId */, const std::string& /* messageId */, const std::string& /* reactionId */){}
virtual void conversationProfileUpdated(const std::string& /*accountId*/, const std::string& /* conversationId */, std::map<std::string, std::string> /*profile*/){}
virtual void conversationRequestReceived(const std::string& /*accountId*/, const std::string& /* conversationId */, std::map<std::string, std::string> /*metadatas*/){}
virtual void conversationRequestDeclined(const std::string& /*accountId*/, const std::string& /* conversationId */){}
Expand Down
5 changes: 5 additions & 0 deletions bin/jni/jni_interface.i
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,13 @@ void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM

const std::map<std::string, SharedCallback> conversationHandlers = {
exportable_callback<ConversationSignal::ConversationLoaded>(bind(&ConversationCallback::conversationLoaded, convM, _1, _2, _3, _4)),
exportable_callback<ConversationSignal::SwarmLoaded>(bind(&ConversationCallback::swarmLoaded, convM, _1, _2, _3, _4)),
exportable_callback<ConversationSignal::MessagesFound>(bind(&ConversationCallback::messagesFound, convM, _1, _2, _3, _4)),
exportable_callback<ConversationSignal::MessageReceived>(bind(&ConversationCallback::messageReceived, convM, _1, _2, _3)),
exportable_callback<ConversationSignal::SwarmMessageReceived>(bind(&ConversationCallback::swarmMessageReceived, convM, _1, _2, _3)),
exportable_callback<ConversationSignal::SwarmMessageUpdated>(bind(&ConversationCallback::swarmMessageUpdated, convM, _1, _2, _3)),
exportable_callback<ConversationSignal::ReactionAdded>(bind(&ConversationCallback::reactionAdded, convM, _1, _2, _3, _4)),
exportable_callback<ConversationSignal::ReactionRemoved>(bind(&ConversationCallback::reactionRemoved, convM, _1, _2, _3, _4)),
exportable_callback<ConversationSignal::ConversationProfileUpdated>(bind(&ConversationCallback::conversationProfileUpdated, convM, _1, _2, _3)),
exportable_callback<ConversationSignal::ConversationRequestReceived>(bind(&ConversationCallback::conversationRequestReceived, convM, _1, _2, _3)),
exportable_callback<ConversationSignal::ConversationRequestDeclined>(bind(&ConversationCallback::conversationRequestDeclined, convM, _1, _2)),
Expand Down
Loading

0 comments on commit 8468f15

Please sign in to comment.