Skip to content
Snippets Groups Projects
Unverified Commit 639fce5f authored by Sébastien Blin's avatar Sébastien Blin
Browse files

newcallmodel: setActiveParticipant accepts URI

Change-Id: Iff79da1f583cd57402f20d1ad631a6d5e5d918d9
parent bbfb03b6
Branches
No related tags found
No related merge requests found
......@@ -31,23 +31,26 @@ namespace Video {
class Renderer;
}
namespace lrc
{
namespace lrc {
class CallbacksHandler;
class NewCallModelPimpl;
namespace api
{
namespace api {
namespace account { struct Info; }
namespace call { struct Info; }
namespace account {
struct Info;
}
namespace call {
struct Info;
}
class NewAccountModel;
/**
* @brief Class that manages call informations.
*/
class LIB_EXPORT NewCallModel : public QObject {
class LIB_EXPORT NewCallModel : public QObject
{
Q_OBJECT
public:
......@@ -55,11 +58,7 @@ public:
const account::Info& owner;
enum class Media {
NONE,
AUDIO,
VIDEO
};
enum class Media { NONE, AUDIO, VIDEO };
NewCallModel(const account::Info& owner, const CallbacksHandler& callbacksHandler);
~NewCallModel();
......@@ -188,7 +187,9 @@ public:
* @param audioOnly If the call is audio only
* @return id for a new call
*/
Q_INVOKABLE QString callAndAddParticipant(const QString uri, const QString& callId, bool audioOnly);
Q_INVOKABLE QString callAndAddParticipant(const QString uri,
const QString& callId,
bool audioOnly);
/**
* Not implemented yet
......@@ -232,6 +233,8 @@ public:
/**
* Set the shown participant
* @param confId The call to change
* @param participant Use contact URI (or callId)
*/
void setActiveParticipant(const QString& confId, const QString& participant);
......@@ -262,7 +265,9 @@ Q_SIGNALS:
* @param fromId the peer uri
* @param displayname
*/
void newIncomingCall(const QString& fromId, const QString& callId, const QString& displayname) const;
void newIncomingCall(const QString& fromId,
const QString& callId,
const QString& displayname) const;
/**
* Emitted when a call is added to a conference
* @param callId
......@@ -277,7 +282,10 @@ Q_SIGNALS:
* @param oldCount
* @param urgentCount
*/
void voiceMailNotify(const QString& accountId, int newCount, int oldCount, int urgentCount) const;
void voiceMailNotify(const QString& accountId,
int newCount,
int oldCount,
int urgentCount) const;
private:
std::unique_ptr<NewCallModelPimpl> pimpl_;
......
......@@ -48,8 +48,8 @@
#include <QString>
static std::uniform_int_distribution<int> dis {0, std::numeric_limits<int>::max()};
static const std::map<short, QString> sip_call_status_code_map {
{0, QObject::tr("Null")},
static const std::map<short, QString>
sip_call_status_code_map {{0, QObject::tr("Null")},
{100, QObject::tr("Trying")},
{180, QObject::tr("Ringing")},
{181, QObject::tr("Being Forwarded")},
......@@ -104,11 +104,9 @@ static const std::map<short, QString> sip_call_status_code_map {
{600, QObject::tr("Busy Everywhere")},
{603, QObject::tr("Call Refused")},
{604, QObject::tr("Does Not Exist Anywhere")},
{606, QObject::tr("Not Acceptable Anywhere")}
};
{606, QObject::tr("Not Acceptable Anywhere")}};
namespace lrc
{
namespace lrc {
using namespace api;
......@@ -131,7 +129,8 @@ public:
/**
* key = peer's uri
* vector = chunks
* @note chunks are counted from 1 to number of parts. We use 0 to store the actual number of parts stored
* @note chunks are counted from 1 to number of parts. We use 0 to store the actual number of
* parts stored
*/
std::map<QString, VectorString> vcardsChunks;
......@@ -155,7 +154,10 @@ public Q_SLOTS:
* @param fromId peer uri
* @param displayname
*/
void slotIncomingCall(const QString& accountId, const QString& callId, const QString& fromId, const QString& displayname);
void slotIncomingCall(const QString& accountId,
const QString& callId,
const QString& fromId,
const QString& displayname);
/**
* Listen from CallbacksHandler when a call got a new state
* @param callId
......@@ -171,7 +173,11 @@ public Q_SLOTS:
* @param numberOfParts
* @param payload
*/
void slotincomingVCardChunk(const QString& callId, const QString& from, int part, int numberOfParts, const QString& payload);
void slotincomingVCardChunk(const QString& callId,
const QString& from,
int part,
int numberOfParts,
const QString& payload);
/**
* Listen from CallbacksHandler when a conference is created.
* @param callId
......@@ -197,12 +203,9 @@ NewCallModel::NewCallModel(const account::Info& owner, const CallbacksHandler& c
: QObject(nullptr)
, owner(owner)
, pimpl_(std::make_unique<NewCallModelPimpl>(*this, callbacksHandler))
{
}
{}
NewCallModel::~NewCallModel()
{
}
NewCallModel::~NewCallModel() {}
const call::Info&
NewCallModel::getCallFromURI(const QString& uri, bool notOver) const
......@@ -213,7 +216,8 @@ NewCallModel::getCallFromURI(const QString& uri, bool notOver) const
auto uriObj = URI(uri);
for (const auto& call : pimpl_->calls) {
auto contactUri = URI(call.second->peerUri);
if (uriObj.userinfo() == contactUri.userinfo() and uriObj.hostname() == contactUri.hostname()) {
if (uriObj.userinfo() == contactUri.userinfo()
and uriObj.hostname() == contactUri.hostname()) {
if (!notOver || !call::isTerminating(call.second->status))
return *call.second;
}
......@@ -233,7 +237,8 @@ NewCallModel::getConferenceFromURI(const QString& uri) const
&& pimpl_->calls[callId]->peerUri == uri) {
return *call.second;
}
} catch (...) {}
} catch (...) {
}
}
}
}
......@@ -250,11 +255,15 @@ QString
NewCallModel::createCall(const QString& uri, bool isAudioOnly)
{
#ifdef ENABLE_LIBWRAP
auto callId = isAudioOnly ? CallManager::instance().placeCall(owner.id, uri, {{"AUDIO_ONLY", "true"}})
auto callId = isAudioOnly
? CallManager::instance().placeCall(owner.id, uri, {{"AUDIO_ONLY", "true"}})
: CallManager::instance().placeCall(owner.id, uri);
#else // dbus
// do not use auto here (QDBusPendingReply<QString>)
QString callId = isAudioOnly ? CallManager::instance().placeCallWithDetails(owner.id, uri, {{"AUDIO_ONLY", "true"}})
QString callId = isAudioOnly
? CallManager::instance().placeCallWithDetails(owner.id,
uri,
{{"AUDIO_ONLY", "true"}})
: CallManager::instance().placeCall(owner.id, uri);
#endif // ENABLE_LIBWRAP
......@@ -284,10 +293,10 @@ NewCallModel::accept(const QString& callId) const
void
NewCallModel::hangUp(const QString& callId) const
{
if (!hasCall(callId)) return;
if (!hasCall(callId))
return;
auto& call = pimpl_->calls[callId];
switch(call->type)
{
switch (call->type) {
case call::Type::DIALOG:
CallManager::instance().hangUp(callId);
break;
......@@ -303,7 +312,8 @@ NewCallModel::hangUp(const QString& callId) const
void
NewCallModel::refuse(const QString& callId) const
{
if (!hasCall(callId)) return;
if (!hasCall(callId))
return;
CallManager::instance().refuse(callId);
}
......@@ -316,15 +326,18 @@ NewCallModel::toggleAudioRecord(const QString& callId) const
void
NewCallModel::playDTMF(const QString& callId, const QString& value) const
{
if (!hasCall(callId)) return;
if (pimpl_->calls[callId]->status != call::Status::IN_PROGRESS) return;
if (!hasCall(callId))
return;
if (pimpl_->calls[callId]->status != call::Status::IN_PROGRESS)
return;
CallManager::instance().playDTMF(value);
}
void
NewCallModel::togglePause(const QString& callId) const
{
if (!hasCall(callId)) return;
if (!hasCall(callId))
return;
auto& call = pimpl_->calls[callId];
if (call->status == call::Status::PAUSED) {
......@@ -346,10 +359,10 @@ NewCallModel::togglePause(const QString& callId) const
void
NewCallModel::toggleMedia(const QString& callId, const NewCallModel::Media media) const
{
if (!hasCall(callId)) return;
if (!hasCall(callId))
return;
auto& call = pimpl_->calls[callId];
switch(media)
{
switch (media) {
case NewCallModel::Media::AUDIO:
CallManager::instance().muteLocalMedia(callId,
DRing::Media::Details::MEDIA_TYPE_AUDIO,
......@@ -407,8 +420,10 @@ NewCallModel::joinCalls(const QString& callIdA, const QString& callIdB) const
call2 = accountInfo.callModel->getCall(callIdB);
accountIdCall2 = account_id;
}
if (!accountIdCall1.isEmpty() && !accountIdCall2.isEmpty()) break;
} catch (...) {}
if (!accountIdCall1.isEmpty() && !accountIdCall2.isEmpty())
break;
} catch (...) {
}
}
if (accountIdCall1.isEmpty() || accountIdCall2.isEmpty()) {
qWarning() << "Can't join inexistent calls.";
......@@ -429,7 +444,8 @@ NewCallModel::joinCalls(const QString& callIdA, const QString& callIdB) const
if (accountInfo.callModel->hasCall(callIdA)) {
emit accountInfo.callModel->callAddedToConference(callIdA, callIdB);
}
} catch (...) {}
} catch (...) {
}
} else {
emit callAddedToConference(callIdA, callIdB);
}
......@@ -452,7 +468,8 @@ NewCallModel::joinCalls(const QString& callIdA, const QString& callIdB) const
if (accountInfo.callModel->hasCall(call)) {
accountInfo.callModel->pimpl_->slotConferenceCreated(conf);
}
} catch (...) {}
} catch (...) {
}
} else
emit callAddedToConference(call, conf);
......@@ -483,19 +500,23 @@ NewCallModel::removeParticipant(const QString& callId, const QString& participan
QString
NewCallModel::getFormattedCallDuration(const QString& callId) const
{
if (!hasCall(callId)) return "00:00";
if (!hasCall(callId))
return "00:00";
auto& startTime = pimpl_->calls[callId]->startTime;
if (startTime.time_since_epoch().count() == 0) return "00:00";
if (startTime.time_since_epoch().count() == 0)
return "00:00";
auto now = std::chrono::steady_clock::now();
auto d = std::chrono::duration_cast<std::chrono::seconds>(
now.time_since_epoch() - startTime.time_since_epoch()).count();
auto d = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()
- startTime.time_since_epoch())
.count();
return authority::storage::getFormattedCallDuration(d);
}
bool
NewCallModel::isRecording(const QString& callId) const
{
if (!hasCall(callId)) return false;
if (!hasCall(callId))
return false;
return CallManager::instance().getIsRecording(callId);
}
......@@ -509,16 +530,35 @@ NewCallModel::getSIPCallStatusString(const short& statusCode)
return "";
}
NewCallModelPimpl::NewCallModelPimpl(const NewCallModel& linked, const CallbacksHandler& callbacksHandler)
NewCallModelPimpl::NewCallModelPimpl(const NewCallModel& linked,
const CallbacksHandler& callbacksHandler)
: linked(linked)
, callbacksHandler(callbacksHandler)
{
connect(&callbacksHandler, &CallbacksHandler::incomingCall, this, &NewCallModelPimpl::slotIncomingCall);
connect(&callbacksHandler, &CallbacksHandler::callStateChanged, this, &NewCallModelPimpl::slotCallStateChanged);
connect(&callbacksHandler, &CallbacksHandler::incomingVCardChunk, this, &NewCallModelPimpl::slotincomingVCardChunk);
connect(&callbacksHandler, &CallbacksHandler::conferenceCreated, this , &NewCallModelPimpl::slotConferenceCreated);
connect(&callbacksHandler, &CallbacksHandler::voiceMailNotify, this, &NewCallModelPimpl::slotVoiceMailNotify);
connect(&CallManager::instance(), &CallManagerInterface::onConferenceInfosUpdated, this, &NewCallModelPimpl::slotOnConferenceInfosUpdated);
connect(&callbacksHandler,
&CallbacksHandler::incomingCall,
this,
&NewCallModelPimpl::slotIncomingCall);
connect(&callbacksHandler,
&CallbacksHandler::callStateChanged,
this,
&NewCallModelPimpl::slotCallStateChanged);
connect(&callbacksHandler,
&CallbacksHandler::incomingVCardChunk,
this,
&NewCallModelPimpl::slotincomingVCardChunk);
connect(&callbacksHandler,
&CallbacksHandler::conferenceCreated,
this,
&NewCallModelPimpl::slotConferenceCreated);
connect(&callbacksHandler,
&CallbacksHandler::voiceMailNotify,
this,
&NewCallModelPimpl::slotVoiceMailNotify);
connect(&CallManager::instance(),
&CallManagerInterface::onConferenceInfosUpdated,
this,
&NewCallModelPimpl::slotOnConferenceInfosUpdated);
#ifndef ENABLE_LIBWRAP
// Only necessary with dbus since the daemon runs separately
......@@ -527,17 +567,13 @@ NewCallModelPimpl::NewCallModelPimpl(const NewCallModel& linked, const Callbacks
#endif
}
NewCallModelPimpl::~NewCallModelPimpl()
{
}
NewCallModelPimpl::~NewCallModelPimpl() {}
void
NewCallModelPimpl::initCallFromDaemon()
{
QStringList callList = CallManager::instance().getCallList();
for (const auto& callId : callList)
{
for (const auto& callId : callList) {
MapStringString details = CallManager::instance().getCallDetails(callId);
auto accountId = details["ACCOUNTID"];
if (accountId == linked.owner.id) {
......@@ -545,7 +581,8 @@ NewCallModelPimpl::initCallFromDaemon()
callInfo->id = callId;
auto now = std::chrono::steady_clock::now();
auto system_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
auto diff = static_cast<int64_t>(system_now) - std::stol(details["TIMESTAMP_START"].toStdString());
auto diff = static_cast<int64_t>(system_now)
- std::stol(details["TIMESTAMP_START"].toStdString());
callInfo->startTime = now - std::chrono::seconds(diff);
callInfo->status = call::to_status(details["CALL_STATE"]);
auto endId = details["PEER_NUMBER"].indexOf("@");
......@@ -570,8 +607,7 @@ void
NewCallModelPimpl::initConferencesFromDaemon()
{
QStringList callList = CallManager::instance().getConferenceList();
for (const auto& callId : callList)
{
for (const auto& callId : callList) {
QMap<QString, QString> details = CallManager::instance().getConferenceDetails(callId);
auto callInfo = std::make_shared<call::Info>();
callInfo->id = callId;
......@@ -580,15 +616,20 @@ NewCallModelPimpl::initConferencesFromDaemon()
foreach (const auto& call, callList) {
MapStringString callDetails = CallManager::instance().getCallDetails(call);
isForThisAccount = callDetails["ACCOUNTID"] == linked.owner.id;
if (!isForThisAccount) break;
if (!isForThisAccount)
break;
auto now = std::chrono::steady_clock::now();
auto system_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
auto diff = static_cast<int64_t>(system_now) - std::stol(callDetails["TIMESTAMP_START"].toStdString());
callInfo->status = details["CONF_STATE"] == "ACTIVE_ATTACHED"? call::Status::IN_PROGRESS : call::Status::PAUSED;
auto diff = static_cast<int64_t>(system_now)
- std::stol(callDetails["TIMESTAMP_START"].toStdString());
callInfo->status = details["CONF_STATE"] == "ACTIVE_ATTACHED"
? call::Status::IN_PROGRESS
: call::Status::PAUSED;
callInfo->startTime = now - std::chrono::seconds(diff);
emit linked.callAddedToConference(call, callId);
}
if (!isForThisAccount) break;
if (!isForThisAccount)
break;
callInfo->type = call::Type::CONFERENCE;
VectorMapStringString infos = CallManager::instance().getConferenceInfos(callId);
callInfo->participantsInfos = infos;
......@@ -599,15 +640,19 @@ NewCallModelPimpl::initConferencesFromDaemon()
void
NewCallModel::setCurrentCall(const QString& callId) const
{
if (!pimpl_->manageCurrentCall_) return;
if (!pimpl_->manageCurrentCall_)
return;
auto it = pimpl_->pendingConferences_.find(callId);
// Set current call only if not adding this call
// to a current conference
if (it != pimpl_->pendingConferences_.end()) return;
if (!hasCall(callId)) return;
if (it != pimpl_->pendingConferences_.end())
return;
if (!hasCall(callId))
return;
// The client should be able to set the current call multiple times
if (pimpl_->currentCall_ == callId) return;
if (pimpl_->currentCall_ == callId)
return;
pimpl_->currentCall_ = callId;
// Unhold call
......@@ -677,9 +722,20 @@ NewCallModel::setConferenceLayout(const QString& confId, const call::Layout& lay
void
NewCallModel::setActiveParticipant(const QString& confId, const QString& participant)
{
CallManager::instance().setActiveParticipant(confId, participant);
QString callId = participant; // participant can be directly the callId
QStringList callList = CallManager::instance().getParticipantList(confId);
for (const auto& call : callList) {
// Search related call for participant given
MapStringString details = CallManager::instance().getCallDetails(call);
auto endId = details["PEER_NUMBER"].indexOf("@");
auto peerUri = details["PEER_NUMBER"].left(endId);
if (peerUri == participant) {
callId = call;
}
}
CallManager::instance().setActiveParticipant(confId, callId);
}
void
NewCallModel::sendSipMessage(const QString& callId, const QString& body) const
......@@ -704,7 +760,10 @@ NewCallModel::hangupCallsAndConferences()
}
void
NewCallModelPimpl::slotIncomingCall(const QString& accountId, const QString& callId, const QString& fromId, const QString& displayname)
NewCallModelPimpl::slotIncomingCall(const QString& accountId,
const QString& callId,
const QString& fromId,
const QString& displayname)
{
if (linked.owner.id != accountId) {
return;
......@@ -722,7 +781,9 @@ NewCallModelPimpl::slotIncomingCall(const QString& accountId, const QString& cal
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;
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;
......@@ -730,7 +791,8 @@ NewCallModelPimpl::slotIncomingCall(const QString& accountId, const QString& cal
callInfo->isAudioOnly = callDetails["AUDIO_ONLY"] == "true" ? true : false;
calls.emplace(callId, std::move(callInfo));
if (!linked.owner.confProperties.allowIncoming && linked.owner.profileInfo.type == profile::Type::RING) {
if (!linked.owner.confProperties.allowIncoming
&& linked.owner.profileInfo.type == profile::Type::RING) {
linked.refuse(callId);
return;
}
......@@ -746,7 +808,8 @@ NewCallModelPimpl::slotIncomingCall(const QString& accountId, const QString& cal
void
NewCallModelPimpl::slotCallStateChanged(const QString& callId, const QString& state, int code)
{
if (!linked.hasCall(callId)) return;
if (!linked.hasCall(callId))
return;
auto status = call::to_status(state);
auto& call = calls[callId];
......@@ -778,10 +841,10 @@ NewCallModelPimpl::slotCallStateChanged(const QString& callId, const QString& st
} else if (call->status == call::Status::IN_PROGRESS) {
if (previousStatus == call::Status::INCOMING_RINGING
|| previousStatus == call::Status::OUTGOING_RINGING) {
if (previousStatus == call::Status::INCOMING_RINGING
&& linked.owner.profileInfo.type != profile::Type::SIP
&& !linked.owner.confProperties.isRendezVous) { // TODO remove this when we want to not show calls in rendez-vous
&& !linked.owner.confProperties.isRendezVous) { // TODO remove this when we want to
// not show calls in rendez-vous
linked.setCurrentCall(callId);
}
call->startTime = std::chrono::steady_clock::now();
......@@ -799,21 +862,19 @@ NewCallModelPimpl::slotCallStateChanged(const QString& callId, const QString& st
}
void
NewCallModelPimpl::slotincomingVCardChunk(const QString& callId,
const QString& from,
int part,
int numberOfParts,
const QString& payload)
NewCallModelPimpl::slotincomingVCardChunk(
const QString& callId, const QString& from, int part, int numberOfParts, const QString& payload)
{
if (!linked.hasCall(callId)) return;
if (!linked.hasCall(callId))
return;
auto it = vcardsChunks.find(from);
if (it != vcardsChunks.end()) {
vcardsChunks[from][part - 1] = payload;
if ( not std::any_of(vcardsChunks[from].begin(), vcardsChunks[from].end(),
if (not std::any_of(vcardsChunks[from].begin(),
vcardsChunks[from].end(),
[](const auto& s) { return s.isEmpty(); })) {
profile::Info profileInfo;
profileInfo.uri = from;
profileInfo.type = profile::Type::RING;
......@@ -842,13 +903,17 @@ NewCallModelPimpl::slotincomingVCardChunk(const QString& callId,
}
void
NewCallModelPimpl::slotVoiceMailNotify(const QString& accountId, int newCount, int oldCount, int urgentCount)
NewCallModelPimpl::slotVoiceMailNotify(const QString& accountId,
int newCount,
int oldCount,
int urgentCount)
{
emit linked.voiceMailNotify(accountId, newCount, oldCount, urgentCount);
}
void
NewCallModelPimpl::slotOnConferenceInfosUpdated(const QString& confId, const VectorMapStringString& infos)
NewCallModelPimpl::slotOnConferenceInfosUpdated(const QString& confId,
const VectorMapStringString& infos)
{
auto it = calls.find(confId);
if (it == calls.end() or not it->second)
......@@ -912,7 +977,6 @@ NewCallModelPimpl::slotConferenceCreated(const QString& confId)
// Remove call from pendingConferences_
pendingConferences_.erase(call);
}
}
void
......@@ -932,8 +996,8 @@ NewCallModelPimpl::sendProfile(const QString& callId)
.arg(lrc::vCard::PROFILE_VCF)
.arg(key.c_str())
.arg(QString::number(i + 1))
.arg( QString::number( total ) )
] = vCard.left(sizeLimit);
.arg(QString::number(total))]
= vCard.left(sizeLimit);
vCard.remove(0, sizeLimit);
++i;
CallManager::instance().sendTextMessage(callId, chunk, false);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment