From 79162515fc2ddb492fc24da80ca2000550971d4f Mon Sep 17 00:00:00 2001 From: Tomasz Sterna Date: Tue, 24 Jun 2014 03:36:17 +0200 Subject: Ported VoiceCallManager from Nemo/voicecall and wired to WatchConnector --- daemon/voicecallhandler.cpp | 418 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100644 daemon/voicecallhandler.cpp (limited to 'daemon/voicecallhandler.cpp') diff --git a/daemon/voicecallhandler.cpp b/daemon/voicecallhandler.cpp new file mode 100644 index 0000000..8e43fb3 --- /dev/null +++ b/daemon/voicecallhandler.cpp @@ -0,0 +1,418 @@ +#include "voicecallhandler.h" + +#include +#include +#include +#include +#include +#include + +/*! + \class VoiceCallHandler + \brief This is the D-Bus proxy for communicating with the voice call manager + from a declarative context, this interface specifically interfaces with + the managers' voice call handler instances. +*/ +class VoiceCallHandlerPrivate +{ + Q_DECLARE_PUBLIC(VoiceCallHandler) + +public: + VoiceCallHandlerPrivate(VoiceCallHandler *q, const QString &pHandlerId) + : q_ptr(q), handlerId(pHandlerId), interface(NULL), connected(false) + , duration(0), status(0), emergency(false), multiparty(false), forwarded(false) + { /* ... */ } + + VoiceCallHandler *q_ptr; + + QString handlerId; + + QDBusInterface *interface; + + bool connected; + int duration; + int status; + QString statusText; + QString lineId; + QString providerId; + QDateTime startedAt; + bool emergency; + bool multiparty; + bool forwarded; +}; + +/*! + Constructs a new proxy interface for the provided voice call handlerId. +*/ +VoiceCallHandler::VoiceCallHandler(const QString &handlerId, QObject *parent) + : QObject(parent), d_ptr(new VoiceCallHandlerPrivate(this, handlerId)) +{ + Q_D(VoiceCallHandler); + qDebug() << QString("Creating D-Bus interface to: ") + handlerId; + d->interface = new QDBusInterface("org.nemomobile.voicecall", + "/calls/" + handlerId, + "org.nemomobile.voicecall.VoiceCall", + QDBusConnection::sessionBus(), + this); + this->initialize(true); +} + +VoiceCallHandler::~VoiceCallHandler() +{ + Q_D(VoiceCallHandler); + delete d; +} + +void VoiceCallHandler::initialize(bool notifyError) +{ + Q_D(VoiceCallHandler); + bool success = false; + +/* +method return sender=:1.13 -> dest=:1.150 reply_serial=2 + string " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +" +*/ + + if(d->interface->isValid()) + { + success = true; + success &= (bool)QObject::connect(d->interface, SIGNAL(error(QString)), SIGNAL(error(QString))); + success &= (bool)QObject::connect(d->interface, SIGNAL(statusChanged()), SLOT(onStatusChanged())); + success &= (bool)QObject::connect(d->interface, SIGNAL(lineIdChanged()), SLOT(onLineIdChanged())); + success &= (bool)QObject::connect(d->interface, SIGNAL(durationChanged()), SLOT(onDurationChanged())); + success &= (bool)QObject::connect(d->interface, SIGNAL(startedAtChanged()), SLOT(onStartedAtChanged())); + success &= (bool)QObject::connect(d->interface, SIGNAL(emergencyChanged()), SLOT(onEmergencyChanged())); + success &= (bool)QObject::connect(d->interface, SIGNAL(multipartyChanged()), SLOT(onMultipartyChanged())); + success &= (bool)QObject::connect(d->interface, SIGNAL(forwardedChanged()), SLOT(onForwardedChanged())); + } + + if(!(d->connected = success)) + { + QTimer::singleShot(2000, this, SLOT(initialize())); + if(notifyError) emit this->error("Failed to connect to VCM D-Bus service."); + } else { + QDBusReply reply = d->interface->call("getProperties"); + if (reply.isValid()) { + QVariantMap props = reply.value(); + qDebug() << "VoiceCallHandler::initialize:" << props; + d->providerId = props["providerId"].toString(); + d->duration = props["duration"].toInt(); + d->status = props["status"].toInt(); + d->statusText = props["statusText"].toString(); + d->lineId = props["lineId"].toString(); + d->startedAt = QDateTime::fromMSecsSinceEpoch(props["startedAt"].toULongLong()); + d->multiparty = props["isMultiparty"].toBool(); + d->emergency = props["isEmergency"].toBool(); + d->forwarded = props["isForwarded"].toBool(); + emit durationChanged(); + emit statusChanged(); + emit lineIdChanged(); + emit startedAtChanged(); + emit multipartyChanged(); + emit emergencyChanged(); + emit forwardedChanged(); + } else if (notifyError) { + emit this->error("Failed to getProperties() from VCM D-Bus service."); + } + } +} + +void VoiceCallHandler::onDurationChanged() +{ + Q_D(VoiceCallHandler); + d->duration = d->interface->property("duration").toInt(); + emit durationChanged(); +} + +void VoiceCallHandler::onStatusChanged() +{ + Q_D(VoiceCallHandler); + d->status = d->interface->property("status").toInt(); + d->statusText = d->interface->property("statusText").toString(); + emit statusChanged(); +} + +void VoiceCallHandler::onLineIdChanged() +{ + Q_D(VoiceCallHandler); + d->lineId = d->interface->property("lineId").toString(); + emit lineIdChanged(); +} + +void VoiceCallHandler::onStartedAtChanged() +{ + Q_D(VoiceCallHandler); + d->startedAt = d->interface->property("startedAt").toDateTime(); + emit startedAtChanged(); +} + +void VoiceCallHandler::onEmergencyChanged() +{ + Q_D(VoiceCallHandler); + d->emergency = d->interface->property("isEmergency").toBool(); + emit emergencyChanged(); +} + +void VoiceCallHandler::onMultipartyChanged() +{ + Q_D(VoiceCallHandler); + d->multiparty = d->interface->property("isMultiparty").toBool(); + emit multipartyChanged(); +} + +void VoiceCallHandler::onForwardedChanged() +{ + Q_D(VoiceCallHandler); + d->forwarded = d->interface->property("isForwarded").toBool(); + emit forwardedChanged(); +} + +/*! + Returns this voice calls' handler id. + */ +QString VoiceCallHandler::handlerId() const +{ + Q_D(const VoiceCallHandler); + return d->handlerId; +} + +/*! + Returns this voice calls' provider id. + */ +QString VoiceCallHandler::providerId() const +{ + Q_D(const VoiceCallHandler); + return d->providerId; +} + +/*! + Returns this voice calls' call status. + */ +int VoiceCallHandler::status() const +{ + Q_D(const VoiceCallHandler); + return d->status; +} + +/*! + Returns this voice calls' call status as a symbolic string. + */ +QString VoiceCallHandler::statusText() const +{ + Q_D(const VoiceCallHandler); + return d->statusText; +} + +/*! + Returns this voice calls' remote end-point line id. + */ +QString VoiceCallHandler::lineId() const +{ + Q_D(const VoiceCallHandler); + return d->lineId; +} + +/*! + Returns this voice calls' started at property. + */ +QDateTime VoiceCallHandler::startedAt() const +{ + Q_D(const VoiceCallHandler); + return d->startedAt; +} + +/*! + Returns this voice calls' duration property. + */ +int VoiceCallHandler::duration() const +{ + Q_D(const VoiceCallHandler); + return d->duration; +} + +/*! + Returns this voice calls' incoming call flag property. + */ +bool VoiceCallHandler::isIncoming() const +{ + Q_D(const VoiceCallHandler); + return d->interface->property("isIncoming").toBool(); +} + +/*! + Returns this voice calls' multiparty flag property. + */ +bool VoiceCallHandler::isMultiparty() const +{ + Q_D(const VoiceCallHandler); + return d->multiparty; +} + +/*! + Returns this voice calls' forwarded flag property. + */ +bool VoiceCallHandler::isForwarded() const +{ + Q_D(const VoiceCallHandler); + return d->forwarded; +} + +/*! + Returns this voice calls' emergency flag property. + */ +bool VoiceCallHandler::isEmergency() const +{ + Q_D(const VoiceCallHandler); + return d->emergency; +} + +/*! + Initiates answering this call, if the call is an incoming call. + */ +void VoiceCallHandler::answer() +{ + Q_D(VoiceCallHandler); + QDBusPendingCall call = d->interface->asyncCall("answer"); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*))); +} + +/*! + Initiates droping the call, unless the call is disconnected. + */ +void VoiceCallHandler::hangup() +{ + Q_D(VoiceCallHandler); + QDBusPendingCall call = d->interface->asyncCall("hangup"); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*))); +} + +/*! + Initiates holding the call, unless the call is disconnected. + */ +void VoiceCallHandler::hold(bool on) +{ + Q_D(VoiceCallHandler); + QDBusPendingCall call = d->interface->asyncCall("hold", on); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*))); +} + +/*! + Initiates deflecting the call to the provided target phone number. + */ +void VoiceCallHandler::deflect(const QString &target) +{ + Q_D(VoiceCallHandler); + QDBusPendingCall call = d->interface->asyncCall("deflect", target); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*))); +} + +void VoiceCallHandler::sendDtmf(const QString &tones) +{ + Q_D(VoiceCallHandler); + QDBusPendingCall call = d->interface->asyncCall("sendDtmf", tones); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*))); +} + +void VoiceCallHandler::onPendingCallFinished(QDBusPendingCallWatcher *watcher) +{ + QDBusPendingReply reply = *watcher; + + if (reply.isError()) { + qWarning() << QString::fromLatin1("Received error reply for member: %1 (%2)").arg(reply.reply().member()).arg(reply.error().message()); + emit this->error(reply.error().message()); + watcher->deleteLater(); + } else { + qDebug() << QString::fromLatin1("Received successful reply for member: %1").arg(reply.reply().member()); + } +} -- cgit v1.2.3