From 76fceef7d1f431d510e92dd7e2067e802dee89c3 Mon Sep 17 00:00:00 2001 From: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> Date: Mon, 3 Jun 2019 11:36:38 -0400 Subject: [PATCH] peerdiscovery: add peerdiscoverymodel -used to reveive peer discovery map change signal -get peer discovery map directly by knowing accountId Change-Id: I35faf9360200d86a68b64d17969797bfcaa3695e --- CMakeLists.txt | 2 + src/api/account.h | 2 + src/api/peerdiscoverymodel.h | 81 ++++++++++++++++ src/callbackshandler.cpp | 15 +++ src/callbackshandler.h | 18 ++++ src/newaccountmodel.cpp | 2 + src/peerdiscoverymodel.cpp | 107 ++++++++++++++++++++++ src/qtwrapper/configurationmanager_wrap.h | 4 + src/qtwrapper/presencemanager_wrap.h | 5 + test/mocks/presencemanager_mock.h | 5 + 10 files changed, 241 insertions(+) create mode 100644 src/api/peerdiscoverymodel.h create mode 100644 src/peerdiscoverymodel.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d7c51ca..40437fd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -343,6 +343,7 @@ SET( libringclient_LIB_SRCS src/authority/databasehelper.cpp src/lrc.cpp src/newaccountmodel.cpp + src/peerdiscoverymodel.cpp src/callbackshandler.cpp src/behaviorcontroller.cpp src/datatransfermodel.cpp @@ -483,6 +484,7 @@ SET(libringclient_api_LIB_HDRS src/api/lrc.h src/api/avmodel.h src/api/newaccountmodel.h + src/api/peerdiscoverymodel.h src/api/newcallmodel.h src/api/newcodecmodel.h src/api/newdevicemodel.h diff --git a/src/api/account.h b/src/api/account.h index 8d353d19..6f9ecfe3 100644 --- a/src/api/account.h +++ b/src/api/account.h @@ -40,6 +40,7 @@ class NewCallModel; class NewAccountModel; class NewDeviceModel; class NewCodecModel; +class PeerDiscoveryModel; namespace account { @@ -225,6 +226,7 @@ struct Info std::unique_ptr<lrc::api::NewCallModel> callModel; std::unique_ptr<lrc::api::NewDeviceModel> deviceModel; std::unique_ptr<lrc::api::NewCodecModel> codecModel; + std::unique_ptr<lrc::api::PeerDiscoveryModel> peerDiscoveryModel; NewAccountModel* accountModel {nullptr}; // daemon config diff --git a/src/api/peerdiscoverymodel.h b/src/api/peerdiscoverymodel.h new file mode 100644 index 00000000..5112629e --- /dev/null +++ b/src/api/peerdiscoverymodel.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * Copyright (C) 2019 Savoir-faire Linux Inc. * + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#pragma once + +// std +#include <vector> +#include <map> +#include <memory> +#include <string> + +// Qt +#include <qobject.h> + +// Lrc +#include "typedefs.h" + +namespace lrc +{ + +class CallbacksHandler; +class PeerDiscoveryModelPimpl; + +namespace api +{ + +struct PeerContact +{ + std::string uri; + std::string displayName; +}; + +enum class PeerModelChanged +{ + INSERT, + REMOVE +}; + + +/** + * @brief Class that manages local peer discovery info + */ +class LIB_EXPORT PeerDiscoveryModel : public QObject { + Q_OBJECT +public: + + PeerDiscoveryModel(const CallbacksHandler& callbackHandler, const std::string& accountID); + ~PeerDiscoveryModel(); + /** + * get a map of discovered peers account + * @return a std::vector<PeerContact> + */ + std::vector<PeerContact> getNearbyPeers() const; + +Q_SIGNALS: + /** + * Connect this signal to know when the status of local peer discovery map changed. + */ + void modelChanged(const std::string& contactUri, PeerModelChanged state, const std::string& displayname); + +private: + std::unique_ptr<PeerDiscoveryModelPimpl> pimpl_; +}; + +} // namespace api +} // namespace lrc diff --git a/src/callbackshandler.cpp b/src/callbackshandler.cpp index dad2607e..283d54e3 100644 --- a/src/callbackshandler.cpp +++ b/src/callbackshandler.cpp @@ -64,6 +64,12 @@ CallbacksHandler::CallbacksHandler(const Lrc& parent) &CallbacksHandler::slotNewBuddySubscription, Qt::QueuedConnection); + connect(&PresenceManager::instance(), + &PresenceManagerInterface::nearbyPeerNotification, + this, + &CallbacksHandler::slotNearbyPeerSubscription, + Qt::QueuedConnection); + connect(&ConfigurationManager::instance(), &ConfigurationManagerInterface::contactAdded, this, @@ -248,6 +254,15 @@ CallbacksHandler::slotNewBuddySubscription(const QString& accountId, emit newBuddySubscription(uri.toStdString(), status); } +void +CallbacksHandler::slotNearbyPeerSubscription(const QString& accountId, + const QString& contactUri, + int state, + const QString& displayname) +{ + emit newPeerSubscription(accountId.toStdString(), contactUri.toStdString(), state, displayname.toStdString()); +} + void CallbacksHandler::slotContactAdded(const QString& accountId, const QString& contactUri, diff --git a/src/callbackshandler.h b/src/callbackshandler.h index 098e7b9a..31409cf1 100644 --- a/src/callbackshandler.h +++ b/src/callbackshandler.h @@ -68,6 +68,12 @@ Q_SIGNALS: * @param present if the peer is online. */ void newBuddySubscription(const std::string& contactUri, bool present); + /** + * Connect this signal to get information when peer discovery changes. + * @param contactUri the peer. + * @param state is 0 if the peer is added. + */ + void newPeerSubscription(const std::string& accountId, const std::string& contactUri, int state, const std::string& displayname); /** * Connect this signal to know when a contact is removed by the daemon. * @param accountId the one who lost a contact. @@ -467,6 +473,18 @@ private Q_SLOTS: */ void slotAudioMeterReceived(const QString& id, float level); + /** + * Emit newPeerSubscription + * @param accountId + * @param contactUri + * @param status if the peer is added or removed + * @param displayname is the account display name + */ + void slotNearbyPeerSubscription(const QString& accountId, + const QString& contactUri, + int state, + const QString& displayname); + private: const api::Lrc& parent; }; diff --git a/src/newaccountmodel.cpp b/src/newaccountmodel.cpp index c12703f5..887d613b 100644 --- a/src/newaccountmodel.cpp +++ b/src/newaccountmodel.cpp @@ -31,6 +31,7 @@ #include "api/lrc.h" #include "api/contactmodel.h" #include "api/conversationmodel.h" +#include "api/peerdiscoverymodel.h" #include "api/newcallmodel.h" #include "api/newcodecmodel.h" #include "api/newdevicemodel.h" @@ -582,6 +583,7 @@ NewAccountModelPimpl::addToAccounts(const std::string& accountId) newAcc.callModel = std::make_unique<NewCallModel>(newAcc, callbacksHandler); newAcc.contactModel = std::make_unique<ContactModel>(newAcc, database, callbacksHandler, behaviorController); newAcc.conversationModel = std::make_unique<ConversationModel>(newAcc, lrc, database, callbacksHandler, behaviorController); + newAcc.peerDiscoveryModel = std::make_unique<PeerDiscoveryModel>(callbacksHandler, accountId); newAcc.deviceModel = std::make_unique<NewDeviceModel>(newAcc, callbacksHandler); newAcc.codecModel = std::make_unique<NewCodecModel>(newAcc, callbacksHandler); newAcc.accountModel = &linked; diff --git a/src/peerdiscoverymodel.cpp b/src/peerdiscoverymodel.cpp new file mode 100644 index 00000000..759edc89 --- /dev/null +++ b/src/peerdiscoverymodel.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** + * Copyright (C) 2019 Savoir-faire Linux Inc. * + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ +#include "api/peerdiscoverymodel.h" + +// new LRC +#include "callbackshandler.h" + +// Dbus +#include "dbus/configurationmanager.h" + +namespace lrc +{ + +using namespace api; + +class PeerDiscoveryModelPimpl: public QObject +{ + Q_OBJECT +public: + PeerDiscoveryModelPimpl(PeerDiscoveryModel& linked, + const CallbacksHandler& callbackHandler, + const std::string& accountID); + ~PeerDiscoveryModelPimpl(); + + PeerDiscoveryModel& linked_; + const CallbacksHandler& callbacksHandler_; + const std::string accountID_; + +public Q_SLOTS: + + /** + * Emit peerMapStatusChanged. + * @param accountId + * @param status + */ + void slotPeerMapStatusChanged(const std::string& accountID, const std::string& contactUri, int state, const std::string& displayname); +}; + +PeerDiscoveryModel::PeerDiscoveryModel(const CallbacksHandler& callbacksHandler, const std::string& accountID) +: QObject() +, pimpl_(std::make_unique<PeerDiscoveryModelPimpl>(*this, callbacksHandler, accountID)) +{ +} + +PeerDiscoveryModel::~PeerDiscoveryModel() +{ +} + +PeerDiscoveryModelPimpl::PeerDiscoveryModelPimpl(PeerDiscoveryModel& linked, + const CallbacksHandler& callbacksHandler, + const std::string& accountID) +: linked_(linked) +, callbacksHandler_(callbacksHandler) +, accountID_(accountID) +{ + connect(&callbacksHandler_, &CallbacksHandler::newPeerSubscription, this, &PeerDiscoveryModelPimpl::slotPeerMapStatusChanged); +} + +PeerDiscoveryModelPimpl::~PeerDiscoveryModelPimpl() +{ + disconnect(&callbacksHandler_, &CallbacksHandler::newPeerSubscription, this, &PeerDiscoveryModelPimpl::slotPeerMapStatusChanged); +} + +void +PeerDiscoveryModelPimpl::slotPeerMapStatusChanged(const std::string& accountID, const std::string& contactUri, int state, const std::string& displayname) +{ + if(accountID != accountID_){ + return; + } + emit linked_.modelChanged(contactUri,state == 0 ? PeerModelChanged::INSERT : PeerModelChanged::REMOVE,displayname); + +} + +std::vector<PeerContact> +PeerDiscoveryModel::getNearbyPeers() const +{ + std::vector<PeerContact> result; + const MapStringString nearbyPeers = ConfigurationManager::instance().getNearbyPeers(QString::fromStdString(pimpl_->accountID_)); + result.reserve(nearbyPeers.size()); + + QMap<QString, QString>::const_iterator i = nearbyPeers.constBegin(); + while (i != nearbyPeers.constEnd()) { + result.emplace_back(PeerContact{i.key().toStdString(), i.value().toStdString()}); + ++i; + } + return result; +} + +} // namespace lrc + +#include "api/moc_peerdiscoverymodel.cpp" +#include "peerdiscoverymodel.moc" diff --git a/src/qtwrapper/configurationmanager_wrap.h b/src/qtwrapper/configurationmanager_wrap.h index 703bc068..49bfb046 100644 --- a/src/qtwrapper/configurationmanager_wrap.h +++ b/src/qtwrapper/configurationmanager_wrap.h @@ -621,6 +621,10 @@ public Q_SLOTS: // METHODS return DRing::getMessageStatus(id); } + MapStringString getNearbyPeers(const QString &accountID){ + return convertMap(DRing::getNearbyPeers(accountID.toStdString())); + } + void connectivityChanged() { DRing::connectivityChanged(); } diff --git a/src/qtwrapper/presencemanager_wrap.h b/src/qtwrapper/presencemanager_wrap.h index f1019a74..1ca89e73 100644 --- a/src/qtwrapper/presencemanager_wrap.h +++ b/src/qtwrapper/presencemanager_wrap.h @@ -63,6 +63,10 @@ public: exportable_callback<PresenceSignal::SubscriptionStateChanged>( [this] (const std::string &accountID, const std::string &buddyUri, bool state) { Q_EMIT this->subscriptionStateChanged(QString(accountID.c_str()), QString(buddyUri.c_str()), state); + }), + exportable_callback<PresenceSignal::NearbyPeerNotification>( + [this] (const std::string &accountID, const std::string &buddyUri, int status, const std::string &displayname) { + Q_EMIT this->nearbyPeerNotification(QString(accountID.c_str()), QString(buddyUri.c_str()), status, QString(displayname.c_str())); }) }; } @@ -100,6 +104,7 @@ public Q_SLOTS: // METHODS } Q_SIGNALS: // SIGNALS + void nearbyPeerNotification(const QString &accountID, const QString &buddyUri, int status, const QString &displayname); void newServerSubscriptionRequest(const QString &buddyUri); void serverError(const QString &accountID, const QString &error, const QString &msg); void newBuddyNotification(const QString &accountID, const QString &buddyUri, bool status, const QString &lineStatus); diff --git a/test/mocks/presencemanager_mock.h b/test/mocks/presencemanager_mock.h index facd0919..4d6e2c98 100644 --- a/test/mocks/presencemanager_mock.h +++ b/test/mocks/presencemanager_mock.h @@ -52,6 +52,10 @@ public: { emit newBuddyNotification(accountID, buddyUri, status, lineStatus); } + void emitNearbyPeerNotification(const QString &accountID, const QString &buddyUri, int status, const QString &displayname) + { + emit nearbyPeerNotification(accountID, buddyUri, status, displayname); + } public Q_SLOTS: // METHODS void answerServerRequest(const QString &uri, bool flag) @@ -91,6 +95,7 @@ Q_SIGNALS: // SIGNALS void newServerSubscriptionRequest(const QString &buddyUri); void serverError(const QString &accountID, const QString &error, const QString &msg); void newBuddyNotification(const QString &accountID, const QString &buddyUri, bool status, const QString &lineStatus); + void nearbyPeerNotification(const QString &accountID, const QString &buddyUri, int status, const QString &displayname); void subscriptionStateChanged(const QString &accountID, const QString &buddyUri, bool state); }; -- GitLab