diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 9ab019b9a6c19e4b123d3d50b0c753a9f75b16b6..16e84bbe6a9912622a951ed4abf49cb5b3023eee 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -18,7 +18,6 @@ * 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/contactmodel.h" // Std #include <algorithm> @@ -28,19 +27,17 @@ #include <account_const.h> // LRC +#include "api/contactmodel.h" #include "api/account.h" #include "api/contact.h" #include "api/interaction.h" #include "api/newaccountmodel.h" #include "api/newcallmodel.h" #include "api/conversationmodel.h" +#include "api/newaccountmodel.h" #include "callbackshandler.h" +#include "uri.h" -#include "accountmodel.h" -#include "contactmethod.h" -#include "namedirectory.h" -#include "phonedirectorymodel.h" -#include "bannedcontactmodel.h" #include "private/vcardutils.h" #include "authority/daemon.h" @@ -64,24 +61,27 @@ public: const BehaviorController& behaviorController); ~ContactModelPimpl(); + /** * Fills with contacts based on database's requests * @return if the method succeeds */ bool fillsWithSIPContacts(); + /** * Fills with contacts based on daemon's requests * @return if the method succeeds */ bool fillsWithRINGContacts(); + /** * Add a contact::Info to contacts. - * @note: the cm must corresponds to a profile in the database. - * @param cm ContactMethod. + * @note: the contactId must corresponds to a profile in the database. + * @param contactId * @param type * @param banned whether contact is banned or not */ - void addToContacts(ContactMethod* cm, const profile::Type& type, bool banned = false); + void addToContacts(const std::string& contactId, const profile::Type& type, bool banned = false); /** * Helpers for searchContact. Search for a given RING or SIP contact. */ @@ -111,6 +111,7 @@ public Q_SLOTS: * @param status */ void slotNewBuddySubscription(const std::string& uri, bool status); + /** * Listen CallbacksHandler when a contact is added * @param accountId @@ -118,6 +119,7 @@ public Q_SLOTS: * @param confirmed */ void slotContactAdded(const std::string& accountId, const std::string& contactUri, bool confirmed); + /** * Listen CallbacksHandler when a contact is removed * @param accountId @@ -125,6 +127,7 @@ public Q_SLOTS: * @param banned */ void slotContactRemoved(const std::string& accountId, const std::string& contactUri, bool banned); + /** * Listen CallbacksHandler when a registeredName is found * @param accountId account linked @@ -133,6 +136,7 @@ public Q_SLOTS: * @param registeredName of the contact found */ void slotRegisteredNameFound(const std::string& accountId, int status, const std::string& uri, const std::string& registeredName); + /** * Listen CallbacksHandler when an incoming request arrives * @param accountId account linked @@ -148,6 +152,7 @@ public Q_SLOTS: * @param callId */ void slotIncomingCall(const std::string& fromId, const std::string& callId); + /** * Listen from callbacksHandler for new account interaction and add pending contact if not present * @param accountId @@ -157,6 +162,7 @@ public Q_SLOTS: void slotNewAccountMessage(std::string& accountId, std::string& from, std::map<std::string,std::string> payloads); + /** * Listen from callbacksHandler to know when a file transfer interaction is incoming * @param dringId Daemon's ID for incoming transfer @@ -306,8 +312,8 @@ ContactModel::removeContact(const std::string& contactUri, bool banned) if (emitContactRemoved) { emit contactRemoved(contactUri); } else { - // NOTE: this method is async, slotContactRemoved will be call and - // then the model will be updated. + // NOTE: this method is asynchronous, the model will be updated + // in slotContactRemoved daemon::removeContact(owner, contactUri, banned); } } @@ -386,9 +392,7 @@ ContactModelPimpl::searchRingContact(const URI& query) updateTemporaryMessage(tr("Searching…").toStdString(), uriID); // Default searching - if (auto* account = AccountModel::instance().getById(linked.owner.id.c_str())) { - account->lookupName(QString(uriID.c_str())); - } + ConfigurationManager::instance().lookupName(QString::fromStdString(linked.owner.id), "", QString::fromStdString(uriID)); } } @@ -497,33 +501,27 @@ ContactModelPimpl::fillsWithSIPContacts() } } } + return true; } bool ContactModelPimpl::fillsWithRINGContacts() { - auto account = AccountModel::instance().getById(linked.owner.id.c_str()); - if (not account) { - qDebug() << "ContactModel::fillsWithContacts(), nullptr"; - return false; - } - // Add contacts from daemon const VectorMapStringString& contacts_vector = ConfigurationManager::instance().getContacts(linked.owner.id.c_str()); for (auto contact_info : contacts_vector) { - auto cm = PhoneDirectoryModel::instance().getNumber(contact_info["id"], account); std::lock_guard<std::mutex> lk(contactsMtx_); - addToContacts(cm, linked.owner.profileInfo.type, contact_info["banned"] == "true"); + bool banned = contact_info["banned"] == "true" ? true : false; + addToContacts(contact_info["id"].toStdString(), linked.owner.profileInfo.type, banned); } // Add pending contacts - const VectorMapStringString& pending_tr {ConfigurationManager::instance().getTrustRequests(account->id())}; + const VectorMapStringString& pending_tr {ConfigurationManager::instance().getTrustRequests(linked.owner.id.c_str())}; for (const auto& tr_info : pending_tr) { // Get pending requests. auto payload = tr_info[DRing::Account::TrustRequest::PAYLOAD].toUtf8(); auto contactUri = tr_info[DRing::Account::TrustRequest::FROM]; - auto* cm = PhoneDirectoryModel::instance().getNumber(contactUri, account); const auto vCard = VCardUtils::toHashMap(payload); const auto alias = vCard["FN"]; @@ -538,8 +536,8 @@ ContactModelPimpl::fillsWithRINGContacts() { contact::Info contactInfo; contactInfo.profileInfo = profileInfo; - contactInfo.registeredName = cm->registeredName().toStdString(); - contactInfo.isBanned = account->bannedContactModel()->isBanned(cm); + contactInfo.registeredName = ""; + contactInfo.isBanned = false; { std::lock_guard<std::mutex> lk(contactsMtx_); @@ -573,12 +571,6 @@ ContactModelPimpl::slotContactAdded(const std::string& accountId, const std::str { Q_UNUSED(confirmed) if (accountId != linked.owner.id) return; - auto* account = AccountModel::instance().getById(linked.owner.id.c_str()); - if (not account) { - qDebug() << "ContactModel::slotContactsAdded(), nullptr"; - return; - } - auto* cm = PhoneDirectoryModel::instance().getNumber(QString(contactUri.c_str()), account); auto contact = contacts.find(contactUri); if (contact->second.profileInfo.type == profile::Type::PENDING) { @@ -601,14 +593,9 @@ ContactModelPimpl::slotContactAdded(const std::string& accountId, const std::str // If contact is banned, do not re-add it, simply update its flag and the banned contacts list if (isBanned) { bannedContacts.erase(it); - - /* Update old LRC. - This method should NOT make any function call that requires the contactsMtx_ lock - otherwise we will get into a deadlock. This is only here for old-lrc transition. */ - account->bannedContactModel()->remove(cm, false); } - addToContacts(cm, linked.owner.profileInfo.type, false); + addToContacts(contactUri, linked.owner.profileInfo.type, false); } } @@ -641,16 +628,6 @@ ContactModelPimpl::slotContactRemoved(const std::string& accountId, const std::s if (banned) { contact->second.isBanned = true; - auto* account = AccountModel::instance().getById(linked.owner.id.c_str()); - if (not account) { - qDebug() << "ContactModel::slotContactsRemoved(), nullptr"; - return; - } - auto* cm = PhoneDirectoryModel::instance().getNumber(QString(contactUri.c_str()), account); - - // Update bannedContactModel from old LRC - account->bannedContactModel()->add(cm); - // Update bannedContacts index bannedContacts.emplace_back(contact->second.profileInfo.uri); } else { @@ -680,35 +657,32 @@ ContactModelPimpl::slotContactRemoved(const std::string& accountId, const std::s } void -ContactModelPimpl::addToContacts(ContactMethod* cm, const profile::Type& type, bool banned) +ContactModelPimpl::addToContacts(const std::string& contactId, const profile::Type& type, bool banned) { - if (!cm) { - qDebug() << "addToContacts: Called with NULL contact method."; - } + auto profileId = database::getOrInsertProfile(db, contactId, "", "", + to_string(linked.owner.profileInfo.type)); - auto contactUri = cm->uri().toStdString(); - auto contactId = database::getProfileId(db, contactUri); - if (contactId.empty()) { - contactId = database::getOrInsertProfile(db, contactUri, "", "", - to_string(linked.owner.profileInfo.type)); + auto contactInfo = database::buildContactFromProfileId(db, profileId); + contactInfo.isBanned = banned; + contactInfo.profileInfo.type = type; // PENDING should not be stored in the database + + // lookup address in case of RING contact + if (type == profile::Type::RING) { + ConfigurationManager::instance().lookupAddress(QString::fromStdString(linked.owner.id), + "", QString::fromStdString(contactId)); } - auto contactInfo = database::buildContactFromProfileId(db, contactId); - contactInfo.registeredName = cm->registeredName().toStdString(); - contactInfo.isBanned = banned; - contactInfo.isPresent = cm->isPresent(); contactInfo.profileInfo.type = type; // Because PENDING should not be stored in the database auto iter = contacts.find(contactInfo.profileInfo.uri); if (iter != contacts.end()) { auto info = iter->second; contactInfo.registeredName = info.registeredName; iter->second = contactInfo; - } - else + } else contacts.emplace_hint(iter, contactInfo.profileInfo.uri, contactInfo); if (banned) { - bannedContacts.emplace_back(contactUri); + bannedContacts.emplace_back(contactId); } } @@ -768,35 +742,27 @@ ContactModelPimpl::slotIncomingContactRequest(const std::string& accountId, if (linked.owner.id != accountId) return; - auto* account = AccountModel::instance().getById(linked.owner.id.c_str()); - if (not account) { - qDebug() << "ContactModel::slotIncomingContactRequest(), nullptr"; - return; - } - auto emitTrust = false; { std::lock_guard<std::mutex> lk(contactsMtx_); if (contacts.find(contactUri) == contacts.end()) { - auto* cm = PhoneDirectoryModel::instance().getNumber(URI(contactUri.c_str()), account); const auto vCard = VCardUtils::toHashMap(payload.c_str()); const auto alias = vCard["FN"]; const auto photo = (vCard.find("PHOTO;ENCODING=BASE64;TYPE=PNG") == vCard.end()) ? vCard["PHOTO;ENCODING=BASE64;TYPE=JPEG"] : vCard["PHOTO;ENCODING=BASE64;TYPE=PNG"]; auto profileInfo = profile::Info {contactUri, photo.toStdString(), alias.toStdString(), profile::Type::PENDING}; - auto contactInfo = contact::Info {profileInfo, cm->bestName().toStdString(), cm->isConfirmed(), cm->isPresent()}; + auto contactInfo = contact::Info {profileInfo, "", false, false, false}; contacts.emplace(contactUri, contactInfo); emitTrust = true; database::getOrInsertProfile(db, contactUri, alias.toStdString(), photo.toStdString(), profile::to_string(profile::Type::RING)); - } else - return; + } } - emit linked.contactAdded(contactUri); if (emitTrust) { + emit linked.contactAdded(contactUri); emit behaviorController.newTrustRequest(linked.owner.id, contactUri); } } @@ -804,34 +770,25 @@ ContactModelPimpl::slotIncomingContactRequest(const std::string& accountId, void ContactModelPimpl::slotIncomingCall(const std::string& fromId, const std::string& callId) { - auto* account = AccountModel::instance().getById(linked.owner.id.c_str()); - if (not account) { - qDebug() << "ContactModel::slotIncomingCall(), nullptr"; - return; - } - + bool emitContactAdded = false; { - bool emitContactAdded = false; - { - std::lock_guard<std::mutex> lk(contactsMtx_); - if (contacts.find(fromId) == contacts.end()) { - // Contact not found, load profile from database. - // The conversation model will create an entry and link the incomingCall. - auto* cm = PhoneDirectoryModel::instance().getNumber(QString(fromId.c_str()), account); - auto type = (linked.owner.profileInfo.type == profile::Type::RING) ? profile::Type::PENDING : profile::Type::SIP; - addToContacts(cm, type, false); - emitContactAdded = true; - } + std::lock_guard<std::mutex> lk(contactsMtx_); + if (contacts.find(fromId) == contacts.end()) { + // Contact not found, load profile from database. + // The conversation model will create an entry and link the incomingCall. + auto type = (linked.owner.profileInfo.type == profile::Type::RING) ? profile::Type::PENDING : profile::Type::SIP; + addToContacts(fromId, type, false); + emitContactAdded = true; } - if (emitContactAdded) { - emit linked.contactAdded(fromId); - if (linked.owner.profileInfo.type == profile::Type::RING) { - emit behaviorController.newTrustRequest(linked.owner.id, fromId); - } + } + if (emitContactAdded) { + emit linked.contactAdded(fromId); + if (linked.owner.profileInfo.type == profile::Type::RING) { + emit behaviorController.newTrustRequest(linked.owner.id, fromId); } - emit linked.incomingCallFromPending(fromId, callId); - return; } + + emit linked.incomingCallFromPending(fromId, callId); } void @@ -840,19 +797,14 @@ ContactModelPimpl::slotNewAccountMessage(std::string& accountId, std::map<std::string,std::string> payloads) { if (accountId != linked.owner.id) return; - auto* account = AccountModel::instance().getById(linked.owner.id.c_str()); - if (not account) { - qDebug() << "ContactModel::slotNewAccountMessage(), nullptr"; - return; - } + auto emitNewTrust = false; { std::lock_guard<std::mutex> lk(contactsMtx_); if (contacts.find(from) == contacts.end()) { // Contact not found, load profile from database. // The conversation model will create an entry and link the incomingCall. - auto* cm = PhoneDirectoryModel::instance().getNumber(QString(from.c_str()), account); - addToContacts(cm, profile::Type::PENDING, false); + addToContacts(from, profile::Type::PENDING, false); emitNewTrust = true; } } @@ -866,25 +818,21 @@ void ContactModelPimpl::slotNewAccountTransfer(long long dringId, datatransfer::Info info) { if (info.accountId != linked.owner.id) return; - auto* account = AccountModel::instance().getById(linked.owner.id.c_str()); - if (not account) { - qDebug() << "ContactModel::slotNewAccountTransfer(), nullptr"; - return; - } + bool emitNewTrust = false; { std::lock_guard<std::mutex> lk(contactsMtx_); if (contacts.find(info.peerUri) == contacts.end()) { // Contact not found, load profile from database. // The conversation model will create an entry and link the incomingCall. - auto* cm = PhoneDirectoryModel::instance().getNumber(QString(info.peerUri.c_str()), account); - addToContacts(cm, profile::Type::PENDING, false); + addToContacts(info.peerUri, profile::Type::PENDING, false); emitNewTrust = true; } } if (emitNewTrust) { emit behaviorController.newTrustRequest(linked.owner.id, info.peerUri); } + emit linked.newAccountTransfer(dringId, info); }