diff --git a/src/manager.cpp b/src/manager.cpp index b1bcd148f3f88a55c7ca0d9dd7123a8de61452c4..af3da77be0c40a4dc3009b6b10a08b85eaabb69a 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 0000000000000000000000000000000000000000..99259c1068cd247f36d7b7ee4f773f2e9049432e --- /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 0000000000000000000000000000000000000000..c884d0355283f04a2d12e738c9f1c26743fb9328 --- /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 0fbc601da0a0721967cfacf9ccad2c9e97e9588d..250284bacbf5d3ab948d54ffda04f7ebe8f3866e 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 3be80e0c77c57fa7c7bf8c0211c853c4fa904825..c509c26e27035bea88565b836fa402feb1fbc3d3 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));