diff --git a/src/libclient/api/callmodel.h b/src/libclient/api/callmodel.h index 4c99b9c73ab57c3fb8dfc7f17a4898ef2ab89dcb..5ac5920211733bb9b23c53b548bc10f9c68334ed 100644 --- a/src/libclient/api/callmodel.h +++ b/src/libclient/api/callmodel.h @@ -446,14 +446,16 @@ Q_SIGNALS: */ void callEnded(const QString& callId) const; /** - * Emitted when a call is incoming + * Emitted when a new call is available + * @param peerId the peer uri * @param callId - * @param fromId the peer uri * @param displayname + * @param isOutgoing */ - void newIncomingCall(const QString& fromId, - const QString& callId, - const QString& displayname) const; + void newCall(const QString& peerId, + const QString& callId, + const QString& displayname, + bool isOutgoing) const; /** * Emitted when a call is added to a conference * @param callId diff --git a/src/libclient/api/contactmodel.h b/src/libclient/api/contactmodel.h index 5820d36fb72cb37a7b8d8a3b044f2d256cc1eb3b..9cae1fdcade260fb88608fffe97b0f71b95481f8 100644 --- a/src/libclient/api/contactmodel.h +++ b/src/libclient/api/contactmodel.h @@ -154,9 +154,10 @@ Q_SIGNALS: /** * Connect this signal to know when a call is incoming. * @param fromId peer profile uri - * @param callId incoming call id + * @param callId call id + * @param isOutgoing */ - void incomingCall(const QString& from, const QString& callId) const; + void newCall(const QString& from, const QString& callId, bool isOutgoing) const; /** * Connect this signal to know when a text message arrives for this account * @param accountId diff --git a/src/libclient/api/conversationmodel.h b/src/libclient/api/conversationmodel.h index 1e353934ef6585e4a83d2e83f7ac90b4700e95eb..07536a6feda92818da9637ff6f757cca869fdc94 100644 --- a/src/libclient/api/conversationmodel.h +++ b/src/libclient/api/conversationmodel.h @@ -241,6 +241,7 @@ public: * @param filter the new filter */ void setFilter(const QString& filter); + void setFilterString(const QString& filter); /** * Modify the current filter (will change the result of getFilteredConversations) * @param filter the new filter (example: SIP, RING, REQUEST) diff --git a/src/libclient/callbackshandler.cpp b/src/libclient/callbackshandler.cpp index 549ca36d93199239b0049eecda7dfa52e9cb09be..254b361fa84bf68deac96fea1f935880c86e465b 100644 --- a/src/libclient/callbackshandler.cpp +++ b/src/libclient/callbackshandler.cpp @@ -153,18 +153,6 @@ CallbacksHandler::CallbacksHandler(const Lrc& parent) &CallbacksHandler::slotRegistrationStateChanged, Qt::QueuedConnection); - connect(&CallManager::instance(), - &CallManagerInterface::incomingCall, - this, - &CallbacksHandler::slotIncomingCall, - Qt::QueuedConnection); - - connect(&CallManager::instance(), - &CallManagerInterface::incomingCallWithMedia, - this, - &CallbacksHandler::slotIncomingCallWithMedia, - Qt::QueuedConnection); - connect(&CallManager::instance(), &CallManagerInterface::mediaChangeRequested, this, @@ -448,38 +436,6 @@ CallbacksHandler::slotContactRemoved(const QString& accountId, Q_EMIT contactRemoved(accountId, contactUri, banned); } -void -CallbacksHandler::slotIncomingCall(const QString& accountId, - const QString& callId, - const QString& fromUri) -{ - slotIncomingCallWithMedia(accountId, callId, fromUri, {}); -} - -void -CallbacksHandler::slotIncomingCallWithMedia(const QString& accountId, - const QString& callId, - const QString& fromUri, - const VectorMapStringString& mediaList) -{ - QString displayname; - QString fromQString; - if (fromUri.contains("ring.dht")) { - auto qDisplayname = fromUri.left(fromUri.indexOf("<") + 1); - if (qDisplayname.size() > 2) { - displayname = qDisplayname.left(qDisplayname.indexOf("<") - 1); - } - fromQString = fromUri.right(50); - fromQString = fromQString.left(40); - } else { - auto left = fromUri.indexOf("<") + 1; - auto right = fromUri.indexOf("@"); - fromQString = fromUri.mid(left, right - left); - displayname = fromUri.left(fromUri.indexOf("<") - 1); - } - Q_EMIT incomingCallWithMedia(accountId, callId, fromQString, displayname, mediaList); -} - void CallbacksHandler::slotMediaChangeRequested(const QString& accountId, const QString& callId, diff --git a/src/libclient/callbackshandler.h b/src/libclient/callbackshandler.h index d8e2699ff60e7a70d229b7dcdb25fae9b831cc63..4d62fdca079c2f6d0a65e377f22380c8d3443ce6 100644 --- a/src/libclient/callbackshandler.h +++ b/src/libclient/callbackshandler.h @@ -90,19 +90,6 @@ Q_SIGNALS: * @param confirmed if the contact is trusted. */ void contactAdded(const QString& accountId, const QString& contactUri, bool confirmed); - /** - * Connect this signal to know when a call arrives - * @param accountId the one who receives the call - * @param callId the call id - * @param fromUri the caller uri - * @param displayName the display name of incoming call - * @param mediaList media received - */ - void incomingCallWithMedia(const QString& accountId, - const QString& callId, - const QString& fromUri, - const QString& displayName, - const VectorMapStringString& mediaList); /** * Connect this signal to know when a call arrives * @param accountId the one who receives the call @@ -452,25 +439,6 @@ private Q_SLOTS: const QString& registration_state, unsigned detail_code, const QString& detail_str); - /** - * @deprecated Use slotIncomingCallWithMedia instead - * Get the URI of the peer and emit incomingCall - * @param accountId account linked - * @param callId the incoming call id - * @param fromUri the uri of the peer - */ - void slotIncomingCall(const QString& accountId, const QString& callId, const QString& fromUri); - /** - * Get the URI of the peer and emit incomingCallWithMedia - * @param accountId account linked - * @param callId the incoming call id - * @param fromUri the uri of the peer - * @param mediaList the mediaList received - */ - void slotIncomingCallWithMedia(const QString& accountId, - const QString& callId, - const QString& fromUri, - const VectorMapStringString& mediaList); /** * Get the URI of the peer and emit mediaChangeRequested * @param accountId account linked diff --git a/src/libclient/callmodel.cpp b/src/libclient/callmodel.cpp index 449184f0ed21a08a7f04ca5f45f31b062ce53e04..300366b429fb6180bc3109822ac275438cd32879 100644 --- a/src/libclient/callmodel.cpp +++ b/src/libclient/callmodel.cpp @@ -188,19 +188,6 @@ public: QList<call::PendingConferenceeInfo> pendingConferencees_; public Q_SLOTS: - /** - * Listen from CallbacksHandler when a call is incoming - * @param accountId account which receives the call - * @param callId - * @param fromId peer uri - * @param displayname - * @param mediaList media received - */ - void slotIncomingCallWithMedia(const QString& accountId, - const QString& callId, - const QString& fromId, - const QString& displayname, - const VectorMapStringString& mediaList); /** * Connect this signal to know when a call arrives * @param accountId the one who receives the call @@ -986,10 +973,6 @@ CallModelPimpl::CallModelPimpl(const CallModel& linked, , callbacksHandler(callbacksHandler) , behaviorController(behaviorController) { - connect(&callbacksHandler, - &CallbacksHandler::incomingCallWithMedia, - this, - &CallModelPimpl::slotIncomingCallWithMedia); connect(&callbacksHandler, &CallbacksHandler::mediaChangeRequested, this, @@ -1367,56 +1350,6 @@ CallModel::isConferenceHost(const QString& callId) return call->second->type == lrc::api::call::Type::CONFERENCE; } -void -CallModelPimpl::slotIncomingCallWithMedia(const QString& accountId, - const QString& callId, - const QString& fromId, - const QString& displayname, - const VectorMapStringString& mediaList) -{ - if (linked.owner.id != accountId) { - return; - } - // TODO: uncomment this. For now, the rendez-vous account is showing calls - // if (linked.owner.confProperties.isRendezVous) { - // // Do not notify for calls if rendez vous because it's in a detached - // // mode and auto answer is managed by the daemon - // return; - //} - - auto callInfo = std::make_shared<call::Info>(); - callInfo->id = callId; - // peer uri = ring:<jami_id> or sip number - auto uri = (linked.owner.profileInfo.type != profile::Type::SIP && !fromId.contains("ring:")) - ? "ring:" + fromId - : fromId; - callInfo->peerUri = uri; - callInfo->isOutgoing = false; - callInfo->status = call::Status::INCOMING_RINGING; - callInfo->type = call::Type::DIALOG; - callInfo->isAudioOnly = true; - callInfo->videoMuted = true; - for (const auto& item : mediaList) { - if (item[MediaAttributeKey::MEDIA_TYPE] == MediaAttributeValue::VIDEO) { - callInfo->isAudioOnly = false; - if (!checkMediaDeviceMuted(item)) { - callInfo->videoMuted = false; - break; - } - } - } - callInfo->mediaList = mediaList; - calls.emplace(callId, std::move(callInfo)); - - if (!linked.owner.confProperties.allowIncoming - && linked.owner.profileInfo.type == profile::Type::JAMI) { - linked.refuse(callId); - return; - } - - Q_EMIT linked.newIncomingCall(fromId, callId, displayname); -} - void CallModelPimpl::slotMediaChangeRequested(const QString& accountId, const QString& callId, @@ -1461,9 +1394,58 @@ CallModelPimpl::slotCallStateChanged(const QString& accountId, const QString& state, int code) { - if (accountId != linked.owner.id || !linked.hasCall(callId)) + if (accountId != linked.owner.id) return; + if (!linked.hasCall(callId)) { + auto callInfo = std::make_shared<call::Info>(); + callInfo->id = callId; + MapStringString details = CallManager::instance().getCallDetails(linked.owner.id, callId); + qDebug() << details; + + auto endId = details["PEER_NUMBER"].indexOf("@"); + callInfo->peerUri = details["PEER_NUMBER"].left(endId); + callInfo->isOutgoing = details["CALL_TYPE"] == "1"; + callInfo->status = call::to_status(state); + callInfo->type = call::Type::DIALOG; + callInfo->isAudioOnly = details["AUDIO_ONLY"] == TRUE_STR; + callInfo->videoMuted = details["VIDEO_MUTED"] == TRUE_STR; + callInfo->mediaList = {}; + calls.emplace(callId, std::move(callInfo)); + + if (!(details["CALL_TYPE"] == "1") + && !linked.owner.confProperties.allowIncoming + && linked.owner.profileInfo.type == profile::Type::JAMI) { + linked.refuse(callId); + return; + } + + QString displayname = details["DISPLAY_NAME"]; + QString peerId; + QString peerUri = details["PEER_NUMBER"]; + if (peerUri.contains("ring.dht")) { + peerId = peerUri.right(50); + peerId = peerId.left(40); + if (displayname.isEmpty()) + displayname = details["REGISTERED_NAME"]; + } else { + auto left = std::max(peerUri.indexOf("<"), peerUri.indexOf(":")) + 1; + auto right = peerUri.indexOf("@"); + right = std::max(right, peerUri.indexOf(">")); + peerId = peerUri.mid(left, right - left); + if (displayname.isEmpty()) + displayname = peerId; + } + qDebug() << displayname; + qDebug() << peerId; + + Q_EMIT linked.newCall(peerId, callId, displayname, details["CALL_TYPE"] == "1"); + + // NOTE: signal emission order matters, always emit CallStatusChanged before CallEnded + Q_EMIT linked.callStatusChanged(callId, code); + Q_EMIT behaviorController.callStatusChanged(linked.owner.id, callId); + } + auto status = call::to_status(state); auto& call = calls[callId]; if (!call) diff --git a/src/libclient/contactmodel.cpp b/src/libclient/contactmodel.cpp index c48e083592b46616f4806a56caa21b3bfb6c8d55..035fb07ebe92e6c01ab022f8ec8a506ed334bfe2 100644 --- a/src/libclient/contactmodel.cpp +++ b/src/libclient/contactmodel.cpp @@ -159,12 +159,13 @@ public Q_SLOTS: const QString& registeredName); /** - * Listen from callModel when an incoming call arrives. + * Listen from callModel when an new call is available. * @param fromId * @param callId * @param displayName + * @param isOutgoing */ - void slotIncomingCall(const QString& fromId, const QString& callId, const QString& displayname); + void slotNewCall(const QString& fromId, const QString& callId, const QString& displayname, bool isOutgoing); /** * Listen from callbacksHandler for new account interaction and add pending contact if not present @@ -413,6 +414,7 @@ ContactModel::getSearchResults() const void ContactModel::searchContact(const QString& query) { + qDebug() << "query! " << query; // always reset temporary contact pimpl_->searchResult.clear(); @@ -626,9 +628,9 @@ ContactModelPimpl::ContactModelPimpl(const ContactModel& linked, this, &ContactModelPimpl::slotRegisteredNameFound); connect(&*linked.owner.callModel, - &CallModel::newIncomingCall, + &CallModel::newCall, this, - &ContactModelPimpl::slotIncomingCall); + &ContactModelPimpl::slotNewCall); connect(&callbacksHandler, &lrc::CallbacksHandler::newAccountMessage, this, @@ -666,9 +668,9 @@ ContactModelPimpl::~ContactModelPimpl() this, &ContactModelPimpl::slotRegisteredNameFound); disconnect(&*linked.owner.callModel, - &CallModel::newIncomingCall, + &CallModel::newCall, this, - &ContactModelPimpl::slotIncomingCall); + &ContactModelPimpl::slotNewCall); disconnect(&callbacksHandler, &lrc::CallbacksHandler::newAccountMessage, this, @@ -1027,39 +1029,41 @@ ContactModelPimpl::slotRegisteredNameFound(const QString& accountId, } void -ContactModelPimpl::slotIncomingCall(const QString& fromId, - const QString& callId, - const QString& displayname) +ContactModelPimpl::slotNewCall(const QString& fromId, + const QString& callId, + const QString& displayname, + bool isOutgoing) { - bool emitContactAdded = false; - { - std::lock_guard<std::mutex> lk(contactsMtx_); - auto it = contacts.find(fromId); - if (it == 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::JAMI) - ? profile::Type::PENDING - : profile::Type::SIP; - addToContacts(fromId, type, displayname, false); - emitContactAdded = true; - } else { - // Update the display name - if (!displayname.isEmpty()) { - it->profileInfo.alias = displayname; - storage::createOrUpdateProfile(linked.owner.id, it->profileInfo, true); + if (!isOutgoing) { + bool emitContactAdded = false; + { + std::lock_guard<std::mutex> lk(contactsMtx_); + auto it = contacts.find(fromId); + if (it == 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::JAMI) + ? profile::Type::PENDING + : profile::Type::SIP; + addToContacts(fromId, type, displayname, false); + emitContactAdded = true; + } else { + // Update the display name + if (!displayname.isEmpty()) { + it->profileInfo.alias = displayname; + storage::createOrUpdateProfile(linked.owner.id, it->profileInfo, true); + } } } + if (emitContactAdded) { + if (linked.owner.profileInfo.type == profile::Type::SIP) + Q_EMIT linked.contactAdded(fromId); + else if (linked.owner.profileInfo.type == profile::Type::JAMI) + Q_EMIT behaviorController.newTrustRequest(linked.owner.id, "", fromId); + } else + Q_EMIT linked.profileUpdated(fromId); } - if (emitContactAdded) { - if (linked.owner.profileInfo.type == profile::Type::SIP) - Q_EMIT linked.contactAdded(fromId); - else if (linked.owner.profileInfo.type == profile::Type::JAMI) - Q_EMIT behaviorController.newTrustRequest(linked.owner.id, "", fromId); - } else - Q_EMIT linked.profileUpdated(fromId); - - Q_EMIT linked.incomingCall(fromId, callId); + Q_EMIT linked.newCall(fromId, callId, isOutgoing); } void diff --git a/src/libclient/conversationmodel.cpp b/src/libclient/conversationmodel.cpp index fa0331bd9c1ca8100d85e8b3957dac58e44447aa..5d853fb7984955dcb162324311efc3db7cb51f59 100644 --- a/src/libclient/conversationmodel.cpp +++ b/src/libclient/conversationmodel.cpp @@ -270,8 +270,9 @@ public Q_SLOTS: * Listen from callmodel for new calls. * @param fromId caller uri * @param callId + * @param isOutgoing */ - void slotIncomingCall(const QString& fromId, const QString& callId); + void slotNewCall(const QString& fromId, const QString& callId, bool isOutgoing = false); /** * Listen from callmodel for calls status changed. * @param callId @@ -1817,9 +1818,9 @@ ConversationModelPimpl::ConversationModelPimpl(const ConversationModel& linked, // Call related connect(&*linked.owner.contactModel, - &ContactModel::incomingCall, + &ContactModel::newCall, this, - &ConversationModelPimpl::slotIncomingCall); + &ConversationModelPimpl::slotNewCall); connect(&*linked.owner.callModel, &lrc::api::CallModel::callStatusChanged, this, @@ -1972,9 +1973,9 @@ ConversationModelPimpl::~ConversationModelPimpl() // Call related disconnect(&*linked.owner.contactModel, - &ContactModel::incomingCall, + &ContactModel::newCall, this, - &ConversationModelPimpl::slotIncomingCall); + &ConversationModelPimpl::slotNewCall); disconnect(&*linked.owner.callModel, &lrc::api::CallModel::callStatusChanged, this, @@ -3366,24 +3367,37 @@ ConversationModelPimpl::getIndicesForContact(const QString& uri) const } void -ConversationModelPimpl::slotIncomingCall(const QString& fromId, const QString& callId) +ConversationModelPimpl::slotNewCall(const QString& fromId, const QString& callId, bool isOutgoing) { + if (isOutgoing) { + // search contact + currentFilter = fromId; + invalidateModel(); + searchResults.clear(); + Q_EMIT linked.searchResultUpdated(); + linked.owner.contactModel->searchContact(currentFilter); + Q_EMIT linked.filterChanged(); + } + auto convIds = storage::getConversationsWithPeer(db, fromId); if (convIds.empty()) { // in case if we receive call after removing contact add conversation request; try { auto contact = linked.owner.contactModel->getContact(fromId); - if (contact.profileInfo.type == profile::Type::PENDING && !contact.isBanned + if (!isOutgoing && !contact.isBanned && fromId != linked.owner.profileInfo.uri) { addContactRequest(fromId); } + if (isOutgoing && contact.profileInfo.type == profile::Type::TEMPORARY) { + linked.owner.contactModel->addContact(contact); + } } catch (const std::out_of_range&) { } } auto conversationIndices = getIndicesForContact(fromId); if (conversationIndices.empty()) { - qDebug() << "ConversationModelPimpl::slotIncomingCall, but conversation not found"; + qDebug() << "ConversationModelPimpl::slotNewCall, but conversation not found"; return; // Not a contact } diff --git a/src/libclient/qtwrapper/callmanager_wrap.h b/src/libclient/qtwrapper/callmanager_wrap.h index 7ae7c1fd9845b2e80107fd69a726fb32c630e6cc..26eef875c53234f326196fec3737a324a1653f3f 100644 --- a/src/libclient/qtwrapper/callmanager_wrap.h +++ b/src/libclient/qtwrapper/callmanager_wrap.h @@ -123,21 +123,6 @@ public: QString(callId.c_str()), QString(from.c_str())); }), - exportable_callback<CallSignal::IncomingCallWithMedia>( - [this](const std::string& accountId, - const std::string& callId, - const std::string& from, - const std::vector<std::map<std::string, std::string>>& mediaList) { - LOG_LIBJAMI_SIGNAL4("incomingCallWithMedia", - QString(accountId.c_str()), - QString(callId.c_str()), - QString(from.c_str()), - convertVecMap(mediaList)); - Q_EMIT incomingCallWithMedia(QString(accountId.c_str()), - QString(callId.c_str()), - QString(from.c_str()), - convertVecMap(mediaList)); - }), exportable_callback<CallSignal::MediaChangeRequested>( [this](const std::string& accountId, const std::string& callId, @@ -639,10 +624,6 @@ Q_SIGNALS: // SIGNALS const QString& from, const MapStringString& message); void incomingCall(const QString& accountId, const QString& callId, const QString& from); - void incomingCallWithMedia(const QString& accountId, - const QString& callId, - const QString& from, - const VectorMapStringString& mediaList); void mediaChangeRequested(const QString& accountId, const QString& callId, const VectorMapStringString& mediaList);