From 08f2bc9be3e0ed0cc43fa62f7a8ef43997563b12 Mon Sep 17 00:00:00 2001 From: ayounes <amine.younes-bouacida@savoirfairelinux.com> Date: Thu, 9 Jan 2020 13:14:37 -0500 Subject: [PATCH] plugins: add conversation handler Change-Id: Ic49979693cd0f4608bba3be4e01c38b3a7142275 --- src/manager.cpp | 9 ++- src/plugin/conversationhandler.h | 43 ++++++++++ src/plugin/conversationservicesmanager.h | 99 ++++++++++++++++++++++++ src/plugin/jamipluginmanager.h | 9 ++- src/sip/sipaccountbase.cpp | 17 +++- 5 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 src/plugin/conversationhandler.h create mode 100644 src/plugin/conversationservicesmanager.h diff --git a/src/manager.cpp b/src/manager.cpp index b1bcd148f3..af3da77be0 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -2951,7 +2951,14 @@ Manager::sendTextMessage(const std::string& accountID, const std::string& to, { if (const auto acc = getAccount(accountID)) { try { - return acc->sendTextMessage(to, payloads); + auto& convManager = jami::Manager::instance().getJamiPluginManager() + .getConversationServicesManager(); + std::shared_ptr<jami::ConversationMessage> cm = + std::make_shared<jami::ConversationMessage>(accountID, to, + const_cast<std::map<std::string, + std::string>&>(payloads)); + convManager.sendTextMessage(cm); + return acc->sendTextMessage(cm->to_, cm->data_); } catch (const std::exception& e) { JAMI_ERR("Exception during text message sending: %s", e.what()); } diff --git a/src/plugin/conversationhandler.h b/src/plugin/conversationhandler.h new file mode 100644 index 0000000000..99259c1068 --- /dev/null +++ b/src/plugin/conversationhandler.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2004-2019 Savoir-faire Linux Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once +#include "observer.h" +#include <string> +#include <map> + +namespace jami { +struct ConversationMessage{ + ConversationMessage(const std::string& author, const std::string& to, + std::map<std::string,std::string>& dataMap) : + author_{author}, to_{to}, data_{dataMap} {} + std::string author_; + std::string to_; + std::map<std::string,std::string> data_; +}; + +using ConvMsgPtr = std::shared_ptr<ConversationMessage>; + +using strMapSubjectPtr = std::shared_ptr<PublishObservable<ConvMsgPtr>>; + +class ConversationHandler { + +public: + virtual ~ConversationHandler() = default; + virtual void notifyStrMapSubject(const bool direction , strMapSubjectPtr subject) = 0; +}; +} diff --git a/src/plugin/conversationservicesmanager.h b/src/plugin/conversationservicesmanager.h new file mode 100644 index 0000000000..c884d03552 --- /dev/null +++ b/src/plugin/conversationservicesmanager.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2004-2019 Savoir-faire Linux Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once +// Utils +#include "noncopyable.h" +// Plugin Manager +#include "pluginmanager.h" +#include "conversationhandler.h" +#include "logger.h" +//Manager +#include "manager.h" + +namespace jami { + +using ConversationHandlerPtr = std::unique_ptr<ConversationHandler>; + +class ConversationServicesManager{ +public: + ConversationServicesManager(PluginManager& pm){ + registerComponentsLifeCycleManagers(pm); + + auto sendTextMessage = [this](const DLPlugin* plugin, void* data) { + auto cm = static_cast<ConversationMessage*>(data); + jami::Manager::instance().sendTextMessage(cm->author_, cm->to_, cm->data_); + return 0; + }; + + pm.registerService("sendTextMessage", sendTextMessage); + } + NON_COPYABLE(ConversationServicesManager); + +public: + void registerComponentsLifeCycleManagers(PluginManager& pm) { + auto registerConversationHandler = [this](void* data) { + ConversationHandlerPtr ptr{(static_cast<ConversationHandler*>(data))}; + + if(ptr) { + conversationHandlers.push_back(std::make_pair(false, std::move(ptr))); + if(!conversationHandlers.empty()) { + listAvailableSubjects(conversationHandlers.back().second); + } + } + + return 0; + }; + + auto unregisterConversationHandler = [this](void* data) { + for(auto it = conversationHandlers.begin(); it != conversationHandlers.end(); ++it) { + if(it->second.get() == data) { + conversationHandlers.erase(it); + } + } + return 0; + }; + + pm.registerComponentManager("ConversationHandlerManager", + registerConversationHandler, unregisterConversationHandler); + } + + void onTextMessage(std::shared_ptr<ConversationMessage>& cm) { + if(!conversationHandlers.empty()) { + receiveSubject->publish(cm); + } + } + + void sendTextMessage(std::shared_ptr<ConversationMessage>& cm) { + if(!conversationHandlers.empty()) { + sendSubject->publish(cm); + } + } + +private: + + void listAvailableSubjects(ConversationHandlerPtr& plugin) { + plugin->notifyStrMapSubject(false, sendSubject); + plugin->notifyStrMapSubject(true, receiveSubject); + } + +private: + std::list<std::pair<bool, ConversationHandlerPtr>> conversationHandlers; + strMapSubjectPtr sendSubject = std::make_shared<PublishObservable<std::shared_ptr<ConversationMessage>>>(); + strMapSubjectPtr receiveSubject = std::make_shared<PublishObservable<std::shared_ptr<ConversationMessage>>>(); +}; +} diff --git a/src/plugin/jamipluginmanager.h b/src/plugin/jamipluginmanager.h index 0fbc601da0..250284bacb 100644 --- a/src/plugin/jamipluginmanager.h +++ b/src/plugin/jamipluginmanager.h @@ -24,6 +24,7 @@ //Services #include "callservicesmanager.h" +#include "conversationservicesmanager.h" #include <vector> #include <map> @@ -34,7 +35,8 @@ namespace jami { class JamiPluginManager { public: - JamiPluginManager() : csm_{pm_}{ + + JamiPluginManager() : csm_{pm_}, convsm_{pm_}{ registerServices(); } // TODO : improve getPluginDetails @@ -126,6 +128,10 @@ public: return csm_; } + ConversationServicesManager& getConversationServicesManager() { + return convsm_; + } + private: NON_COPYABLE(JamiPluginManager); @@ -202,6 +208,7 @@ private: //Services private: CallServicesManager csm_; + ConversationServicesManager convsm_; }; } diff --git a/src/sip/sipaccountbase.cpp b/src/sip/sipaccountbase.cpp index 3be80e0c77..c509c26e27 100644 --- a/src/sip/sipaccountbase.cpp +++ b/src/sip/sipaccountbase.cpp @@ -49,6 +49,9 @@ #include <ctime> +#include "manager.h" +#include "plugin/jamipluginmanager.h" + namespace jami { static constexpr const char MIME_TYPE_IMDN[] {"message/imdn+xml"}; @@ -527,10 +530,18 @@ SIPAccountBase::onTextMessage(const std::string& id, const std::string& from, } } } - emitSignal<DRing::ConfigurationSignal::IncomingAccountMessage>(accountID_, id, from, payloads); + + auto& convManager = jami::Manager::instance().getJamiPluginManager() + .getConversationServicesManager(); + std::shared_ptr<ConversationMessage> cm = + std::make_shared<ConversationMessage>(from, accountID_, + const_cast<std::map<std::string, std::string>&>(payloads)); + convManager.onTextMessage(cm); + emitSignal<DRing::ConfigurationSignal::IncomingAccountMessage>(accountID_, id, from, cm->data_); + DRing::Message message; - message.from = from; - message.payloads = payloads; + message.from = cm->author_; + message.payloads = cm->data_; message.received = std::time(nullptr); std::lock_guard<std::mutex> lck(mutexLastMessages_); lastMessages_.emplace_back(std::move(message)); -- GitLab