summaryrefslogtreecommitdiff
path: root/rockworkd
diff options
context:
space:
mode:
authorAndrew Branson <andrew.branson@cern.ch>2016-02-17 20:41:52 +0100
committerAndrew Branson <andrew.branson@cern.ch>2016-02-17 20:41:52 +0100
commit0f3d090bd1dc9a6b912eb0b1e587602573304b4a (patch)
treeaa52d58d9ba119d20d491a37595c3fa4f3458980 /rockworkd
parent07fb609095291f8d8544441925dea3d60d636f87 (diff)
First attempt at QML hacking.
Main and ServiceControl adapted. Project files
Diffstat (limited to 'rockworkd')
-rw-r--r--rockworkd/jsfiles.qrc2
-rw-r--r--rockworkd/libpebble/watchconnection.cpp18
-rw-r--r--rockworkd/platformintegration/sailfish/callchannelobserver.cpp9
-rw-r--r--rockworkd/platformintegration/sailfish/callchannelobserver.h2
-rw-r--r--rockworkd/platformintegration/sailfish/sailfishplatform.h6
-rw-r--r--rockworkd/platformintegration/sailfish/voicecallhandler.cpp372
-rw-r--r--rockworkd/platformintegration/sailfish/voicecallhandler.h96
-rw-r--r--rockworkd/platformintegration/sailfish/voicecallmanager.cpp315
-rw-r--r--rockworkd/platformintegration/sailfish/voicecallmanager.h111
-rw-r--r--rockworkd/rockworkd.pro23
10 files changed, 926 insertions, 28 deletions
diff --git a/rockworkd/jsfiles.qrc b/rockworkd/jsfiles.qrc
deleted file mode 100644
index 807350d..0000000
--- a/rockworkd/jsfiles.qrc
+++ /dev/null
@@ -1,2 +0,0 @@
-<RCC/>
-
diff --git a/rockworkd/libpebble/watchconnection.cpp b/rockworkd/libpebble/watchconnection.cpp
index 0778a1d..dabacf4 100644
--- a/rockworkd/libpebble/watchconnection.cpp
+++ b/rockworkd/libpebble/watchconnection.cpp
@@ -32,7 +32,7 @@ UploadManager *WatchConnection::uploadManager() const
void WatchConnection::scheduleReconnect()
{
- if (m_connectionAttempts == 0) {
+ if (m_connectionAttempts < 2) {
reconnect();
} else if (m_connectionAttempts < 25) {
qDebug() << "Attempting to reconnect in 10 seconds";
@@ -49,21 +49,27 @@ void WatchConnection::scheduleReconnect()
void WatchConnection::reconnect()
{
QBluetoothLocalDevice localBtDev;
+ qDebug() << "Reconnection";
if (localBtDev.pairingStatus(m_pebbleAddress) == QBluetoothLocalDevice::Unpaired) {
// Try again in one 10 secs, give the user some time to pair it
+ qDebug() << "Unpaired.";
m_connectionAttempts = 1;
scheduleReconnect();
return;
}
if (m_socket) {
+ qDebug() << "Socket exists.";
if (m_socket->state() == QBluetoothSocket::ConnectedState) {
qDebug() << "Already connected.";
return;
}
- delete m_socket;
+ m_socket->deleteLater();
}
+ m_connectionAttempts++;
+
+ qDebug() << "Creating socket.";
m_socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this);
connect(m_socket, &QBluetoothSocket::connected, this, &WatchConnection::pebbleConnected);
connect(m_socket, &QBluetoothSocket::readyRead, this, &WatchConnection::readyRead);
@@ -71,7 +77,6 @@ void WatchConnection::reconnect()
connect(m_socket, &QBluetoothSocket::disconnected, this, &WatchConnection::pebbleDisconnected);
//connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(onBytesWritten(qint64)));
- m_connectionAttempts++;
// FIXME: Assuming port 1 (with Pebble)
m_socket->connectToService(m_pebbleAddress, 1);
@@ -141,8 +146,12 @@ void WatchConnection::pebbleConnected()
void WatchConnection::pebbleDisconnected()
{
qDebug() << "Disconnected";
- m_socket->close();
+
emit watchDisconnected();
+ QBluetoothSocket *socket = qobject_cast<QBluetoothSocket *>(sender());
+ if (!socket) return;
+
+ socket->deleteLater();
if (!m_reconnectTimer.isActive()) {
scheduleReconnect();
}
@@ -152,7 +161,6 @@ void WatchConnection::socketError(QBluetoothSocket::SocketError error)
{
Q_UNUSED(error); // We seem to get UnknownError anyways all the time
qDebug() << "SocketError" << error;
- m_socket->close();
emit watchConnectionFailed();
if (!m_reconnectTimer.isActive()) {
scheduleReconnect();
diff --git a/rockworkd/platformintegration/sailfish/callchannelobserver.cpp b/rockworkd/platformintegration/sailfish/callchannelobserver.cpp
index 534c360..a9f41f3 100644
--- a/rockworkd/platformintegration/sailfish/callchannelobserver.cpp
+++ b/rockworkd/platformintegration/sailfish/callchannelobserver.cpp
@@ -15,9 +15,10 @@ TelepathyMonitor::TelepathyMonitor(QObject *parent):
QObject(parent)
{
Tp::registerTypes();
- QTimer::singleShot(0, this, SLOT(accountManagerSetup));
- m_contactManager = new QContactManager("org.nemomobile.contacts.sqlite");
- m_contactManager->setParent(this);
+ QTimer::singleShot(0, this, SLOT(accountManagerSetup()));
+ QMap<QString, QString> parameters;
+ parameters.insert(QString::fromLatin1("mergePresenceChanges"), QString::fromLatin1("false"));
+ m_contactManager = new QContactManager("", parameters, this);
}
void TelepathyMonitor::hangupCall(uint cookie)
@@ -42,7 +43,7 @@ void TelepathyMonitor::accountManagerReady(Tp::PendingOperation* operation)
{
if (operation->isError()) {
qDebug() << "TelepathyMonitor: accountManager init error.";
- QTimer::singleShot(1000, this, SLOT(TelepathyMonitor::accountManagerSetup)); // again
+ QTimer::singleShot(1000, this, SLOT(accountManagerSetup())); // again
return;
}
qDebug() << "Telepathy account manager ready";
diff --git a/rockworkd/platformintegration/sailfish/callchannelobserver.h b/rockworkd/platformintegration/sailfish/callchannelobserver.h
index cc2b7aa..ba3415d 100644
--- a/rockworkd/platformintegration/sailfish/callchannelobserver.h
+++ b/rockworkd/platformintegration/sailfish/callchannelobserver.h
@@ -27,7 +27,7 @@ public:
signals:
void callStarted(Tp::CallChannelPtr callChannel);
-// void callEnded();
+ void callEnded();
private:
Tp::AccountPtr mAccount;
diff --git a/rockworkd/platformintegration/sailfish/sailfishplatform.h b/rockworkd/platformintegration/sailfish/sailfishplatform.h
index dd4f56d..e18b986 100644
--- a/rockworkd/platformintegration/sailfish/sailfishplatform.h
+++ b/rockworkd/platformintegration/sailfish/sailfishplatform.h
@@ -1,5 +1,5 @@
-#ifndef UBUNTUPLATFORM_H
-#define UBUNTUPLATFORM_H
+#ifndef SAILFISHPLATFORM_H
+#define SAILFISHPLATFORM_H
#include "libpebble/platforminterface.h"
#include "libpebble/enums.h"
@@ -55,4 +55,4 @@ private:
QTimer m_syncTimer;
};
-#endif // UBUNTUPLATFORM_H
+#endif // SAILFISHPLATFORM_H
diff --git a/rockworkd/platformintegration/sailfish/voicecallhandler.cpp b/rockworkd/platformintegration/sailfish/voicecallhandler.cpp
new file mode 100644
index 0000000..2ae5087
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/voicecallhandler.cpp
@@ -0,0 +1,372 @@
+#include "voicecallhandler.h"
+
+#include <QDebug>
+#include <QDBusInterface>
+#include <QDBusPendingReply>
+#include <QDBusReply>
+#include <QVariantMap>
+
+/*!
+ \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)
+ , duration(0), status(0), emergency(false), incoming(false)
+ , multiparty(false) , forwarded(false), remoteHeld(false)
+ { /* ... */ }
+
+ VoiceCallHandler *q_ptr;
+
+ QString handlerId;
+
+ QDBusInterface *interface;
+
+ int duration;
+ int status;
+ QString statusText;
+ QString lineId;
+ QString providerId;
+ QDateTime startedAt;
+ bool emergency;
+ bool incoming;
+ bool multiparty;
+ bool forwarded;
+ bool remoteHeld;
+};
+
+/*!
+ Constructs a new proxy interface for the provided voice call handlerId.
+*/
+VoiceCallHandler::VoiceCallHandler(const QString &handlerId, QObject *parent)
+ : QObject(parent), l(metaObject()->className()), d_ptr(new VoiceCallHandlerPrivate(this, handlerId))
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << 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);
+
+ if (d->interface->isValid()) {
+ if (getProperties()) {
+ emit durationChanged();
+ emit statusChanged();
+ emit lineIdChanged();
+ emit startedAtChanged();
+ emit multipartyChanged();
+ emit emergencyChanged();
+ emit forwardedChanged();
+
+ connect(d->interface, SIGNAL(error(QString)), SIGNAL(error(QString)));
+ connect(d->interface, SIGNAL(statusChanged(int, QString)), SLOT(onStatusChanged(int, QString)));
+ connect(d->interface, SIGNAL(lineIdChanged(QString)), SLOT(onLineIdChanged(QString)));
+ connect(d->interface, SIGNAL(durationChanged(int)), SLOT(onDurationChanged(int)));
+ connect(d->interface, SIGNAL(startedAtChanged(QDateTime)), SLOT(onStartedAtChanged(QDateTime)));
+ connect(d->interface, SIGNAL(emergencyChanged(bool)), SLOT(onEmergencyChanged(bool)));
+ connect(d->interface, SIGNAL(multipartyChanged(bool)), SLOT(onMultipartyChanged(bool)));
+ connect(d->interface, SIGNAL(forwardedChanged(bool)), SLOT(onForwardedChanged(bool)));
+ connect(d->interface, SIGNAL(remoteHeldChanged(bool)), SLOT(onRemoteHeldChanged(bool)));
+ }
+ else {
+ if (notifyError) emit this->error("Failed to get VoiceCall properties from VCM D-Bus service.");
+ }
+ }
+ else {
+ qCCritical(l) << d->interface->lastError().name() << d->interface->lastError().message();
+ }
+}
+
+bool VoiceCallHandler::getProperties()
+{
+ Q_D(VoiceCallHandler);
+
+ QDBusInterface props(d->interface->service(), d->interface->path(),
+ "org.freedesktop.DBus.Properties", d->interface->connection());
+
+ QDBusReply<QVariantMap> reply = props.call("GetAll", d->interface->interface());
+ if (reply.isValid()) {
+ QVariantMap props = reply.value();
+ qCDebug(l) << 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();
+ d->incoming = props["isIncoming"].toBool();
+ d->remoteHeld = props["isIncoming"].toBool();
+ return true;
+ }
+ else {
+ qCCritical(l) << "Failed to get VoiceCall properties from VCM D-Bus service.";
+ return false;
+ }
+}
+
+void VoiceCallHandler::onDurationChanged(int duration)
+{
+ Q_D(VoiceCallHandler);
+ //qCDebug(l) <<"onDurationChanged"<<duration;
+ d->duration = duration;
+ emit durationChanged();
+}
+
+void VoiceCallHandler::onStatusChanged(int status, QString statusText)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) <<"onStatusChanged" << status << statusText;
+ d->status = status;
+ d->statusText = statusText;
+ if (status) getProperties(); // make sure all properties are present
+ emit statusChanged();
+}
+
+void VoiceCallHandler::onLineIdChanged(QString lineId)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onLineIdChanged" << lineId;
+ d->lineId = lineId;
+ emit lineIdChanged();
+}
+
+void VoiceCallHandler::onStartedAtChanged(const QDateTime &startedAt)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onStartedAtChanged" << startedAt;
+ d->startedAt = d->interface->property("startedAt").toDateTime();
+ emit startedAtChanged();
+}
+
+void VoiceCallHandler::onEmergencyChanged(bool isEmergency)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onEmergencyChanged" << isEmergency;
+ d->emergency = isEmergency;
+ emit emergencyChanged();
+}
+
+void VoiceCallHandler::onMultipartyChanged(bool isMultiparty)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onMultipartyChanged" << isMultiparty;
+ d->multiparty = isMultiparty;
+ emit multipartyChanged();
+}
+
+void VoiceCallHandler::onForwardedChanged(bool isForwarded)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onForwardedChanged" << isForwarded;
+ d->forwarded = isForwarded;
+ emit forwardedChanged();
+}
+
+void VoiceCallHandler::onRemoteHeldChanged(bool isRemoteHeld)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onRemoteHeldChanged" << isRemoteHeld;
+ d->forwarded = isRemoteHeld;
+ emit remoteHeldChanged();
+}
+
+/*!
+ 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->incoming;
+}
+
+/*!
+ 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;
+}
+
+/*!
+ Returns this voice calls' remoteHeld flag property.
+ */
+bool VoiceCallHandler::isRemoteHeld() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->remoteHeld;
+}
+
+/*!
+ 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<bool> reply = *watcher;
+
+ if (reply.isError()) {
+ qCCritical(l) << 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 {
+ qCDebug(l) << QString::fromLatin1("Received successful reply for member: %1").arg(reply.reply().member());
+ }
+}
diff --git a/rockworkd/platformintegration/sailfish/voicecallhandler.h b/rockworkd/platformintegration/sailfish/voicecallhandler.h
new file mode 100644
index 0000000..e718abb
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/voicecallhandler.h
@@ -0,0 +1,96 @@
+#ifndef VOICECALLHANDLER_H
+#define VOICECALLHANDLER_H
+
+#include <QObject>
+#include <QDateTime>
+#include <QDBusPendingCallWatcher>
+#include <QLoggingCategory>
+
+class VoiceCallHandler : public QObject
+{
+ Q_OBJECT
+ QLoggingCategory l;
+
+ Q_ENUMS(VoiceCallStatus)
+
+ Q_PROPERTY(QString handlerId READ handlerId CONSTANT)
+ Q_PROPERTY(QString providerId READ providerId CONSTANT)
+ Q_PROPERTY(int status READ status NOTIFY statusChanged)
+ Q_PROPERTY(QString statusText READ statusText NOTIFY statusChanged)
+ Q_PROPERTY(QString lineId READ lineId NOTIFY lineIdChanged)
+ Q_PROPERTY(QDateTime startedAt READ startedAt NOTIFY startedAtChanged)
+ Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(bool isIncoming READ isIncoming CONSTANT)
+ Q_PROPERTY(bool isEmergency READ isEmergency NOTIFY emergencyChanged)
+ Q_PROPERTY(bool isMultiparty READ isMultiparty NOTIFY multipartyChanged)
+ Q_PROPERTY(bool isForwarded READ isForwarded NOTIFY forwardedChanged)
+ Q_PROPERTY(bool isRemoteHeld READ isRemoteHeld NOTIFY remoteHeldChanged)
+
+public:
+ enum VoiceCallStatus {
+ STATUS_NULL,
+ STATUS_ACTIVE,
+ STATUS_HELD,
+ STATUS_DIALING,
+ STATUS_ALERTING,
+ STATUS_INCOMING,
+ STATUS_WAITING,
+ STATUS_DISCONNECTED
+ };
+
+ explicit VoiceCallHandler(const QString &handlerId, QObject *parent = 0);
+ ~VoiceCallHandler();
+
+ QString handlerId() const;
+ QString providerId() const;
+ int status() const;
+ QString statusText() const;
+ QString lineId() const;
+ QDateTime startedAt() const;
+ int duration() const;
+ bool isIncoming() const;
+ bool isMultiparty() const;
+ bool isEmergency() const;
+ bool isForwarded() const;
+ bool isRemoteHeld() const;
+
+Q_SIGNALS:
+ void error(const QString &error);
+ void statusChanged();
+ void lineIdChanged();
+ void durationChanged();
+ void startedAtChanged();
+ void emergencyChanged();
+ void multipartyChanged();
+ void forwardedChanged();
+ void remoteHeldChanged();
+
+public Q_SLOTS:
+ void answer();
+ void hangup();
+ void hold(bool on);
+ void deflect(const QString &target);
+ void sendDtmf(const QString &tones);
+
+protected Q_SLOTS:
+ void initialize(bool notifyError = false);
+ bool getProperties();
+
+ void onPendingCallFinished(QDBusPendingCallWatcher *watcher);
+ void onDurationChanged(int duration);
+ void onStatusChanged(int status, QString statusText);
+ void onLineIdChanged(QString lineId);
+ void onStartedAtChanged(const QDateTime &startedAt);
+ void onEmergencyChanged(bool isEmergency);
+ void onMultipartyChanged(bool isMultiparty);
+ void onForwardedChanged(bool isForwarded);
+ void onRemoteHeldChanged(bool isRemoteHeld);
+
+private:
+ class VoiceCallHandlerPrivate *d_ptr;
+
+ Q_DISABLE_COPY(VoiceCallHandler)
+ Q_DECLARE_PRIVATE(VoiceCallHandler)
+};
+
+#endif // VOICECALLHANDLER_H
diff --git a/rockworkd/platformintegration/sailfish/voicecallmanager.cpp b/rockworkd/platformintegration/sailfish/voicecallmanager.cpp
new file mode 100644
index 0000000..afb3629
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/voicecallmanager.cpp
@@ -0,0 +1,315 @@
+#include "voicecallmanager.h"
+
+#include <QDebug>
+#include <QTimer>
+#include <QDBusInterface>
+#include <QDBusPendingReply>
+
+class VoiceCallManagerPrivate
+{
+ Q_DECLARE_PUBLIC(VoiceCallManager)
+
+public:
+ VoiceCallManagerPrivate(VoiceCallManager *q)
+ : q_ptr(q),
+ interface(NULL),
+ activeVoiceCall(NULL),
+ connected(false)
+ { /*...*/ }
+
+ VoiceCallManager *q_ptr;
+
+ QDBusInterface *interface;
+
+ QList<VoiceCallHandler*> voicecalls;
+ QHash<QString,VoiceCallProviderData> providers;
+
+ VoiceCallHandler* activeVoiceCall;
+
+ bool connected;
+};
+
+VoiceCallManager::VoiceCallManager(Settings *settings, QObject *parent)
+ : QObject(parent), l(metaObject()->className()), d_ptr(new VoiceCallManagerPrivate(this)), settings(settings)
+{
+ this->initialize();
+}
+
+VoiceCallManager::~VoiceCallManager()
+{
+ Q_D(VoiceCallManager);
+ delete d;
+}
+
+void VoiceCallManager::initialize(bool notifyError)
+{
+ Q_D(VoiceCallManager);
+ bool success = false;
+
+ delete d->interface;
+ d->interface = new QDBusInterface("org.nemomobile.voicecall",
+ "/",
+ "org.nemomobile.voicecall.VoiceCallManager",
+ QDBusConnection::sessionBus(),
+ this);
+
+ 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(voiceCallsChanged()), SLOT(onVoiceCallsChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(providersChanged()), SLOT(onProvidersChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(activeVoiceCallChanged()), SLOT(onActiveVoiceCallChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(audioModeChanged()), SIGNAL(audioModeChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(audioRoutedChanged()), SIGNAL(audioRoutedChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(microphoneMutedChanged()), SIGNAL(microphoneMutedChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(speakerMutedChanged()), SIGNAL(speakerMutedChanged()));
+
+ onVoiceCallsChanged();
+ onActiveVoiceCallChanged();
+ }
+
+ if(!(d->connected = success))
+ {
+ QTimer::singleShot(2000, this, SLOT(initialize()));
+ if(notifyError) emit this->error("Failed to connect to VCM D-Bus service.");
+ }
+}
+
+QDBusInterface* VoiceCallManager::interface() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface;
+}
+
+VoiceCallHandlerList VoiceCallManager::voiceCalls() const
+{
+ Q_D(const VoiceCallManager);
+ return d->voicecalls;
+}
+
+VoiceCallProviderHash VoiceCallManager::providers() const
+{
+ Q_D(const VoiceCallManager);
+ return d->providers;
+}
+
+QString VoiceCallManager::defaultProviderId() const
+{
+ Q_D(const VoiceCallManager);
+ if(d->providers.count() == 0) {
+ qCDebug(l) << Q_FUNC_INFO << "No provider added";
+ return QString::null;
+ }
+
+ QStringList keys = d->providers.keys();
+ qSort(keys);
+
+ VoiceCallProviderData provider = d->providers.value(keys.value(0));
+ return provider.id;
+}
+
+VoiceCallHandler* VoiceCallManager::activeVoiceCall() const
+{
+ Q_D(const VoiceCallManager);
+ return d->activeVoiceCall;
+}
+
+QString VoiceCallManager::audioMode() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface->property("audioMode").toString();
+}
+
+bool VoiceCallManager::isAudioRouted() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface->property("isAudioRouted").toBool();
+}
+
+bool VoiceCallManager::isMicrophoneMuted() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface->property("isMicrophoneMuted").toBool();
+}
+
+bool VoiceCallManager::isSpeakerMuted() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface->property("isSpeakerMuted").toBool();
+}
+
+void VoiceCallManager::dial(const QString &provider, const QString &msisdn)
+{
+ Q_D(VoiceCallManager);
+ QDBusPendingCall call = d->interface->asyncCall("dial", provider, msisdn);
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*)));
+}
+
+void VoiceCallManager::hangupAll()
+{
+ foreach (VoiceCallHandler* handler, voiceCalls()) {
+ handler->hangup();
+ }
+}
+
+void VoiceCallManager::silenceRingtone()
+{
+ Q_D(const VoiceCallManager);
+ QDBusPendingCall call = d->interface->asyncCall("silenceRingtone");
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingSilenceFinished(QDBusPendingCallWatcher*)));
+}
+
+/*
+ - Use of method calls instead of property setters to allow status checking.
+ */
+bool VoiceCallManager::setAudioMode(const QString &mode)
+{
+ Q_D(const VoiceCallManager);
+ QDBusPendingReply<bool> reply = d->interface->call("setAudioMode", mode);
+ return reply.isError() ? false : reply.value();
+}
+
+bool VoiceCallManager::setAudioRouted(bool on)
+{
+ Q_D(const VoiceCallManager);
+ QDBusPendingReply<bool> reply = d->interface->call("setAudioRouted", on);
+ return reply.isError() ? false : reply.value();
+}
+
+bool VoiceCallManager::setMuteMicrophone(bool on)
+{
+ Q_D(VoiceCallManager);
+ QDBusPendingReply<bool> reply = d->interface->call("setMuteMicrophone", on);
+ return reply.isError() ? false : reply.value();
+}
+
+bool VoiceCallManager::setMuteSpeaker(bool on)
+{
+ Q_D(VoiceCallManager);
+ QDBusPendingReply<bool> reply = d->interface->call("setMuteSpeaker", on);
+ return reply.isError() ? false : reply.value();
+}
+
+void VoiceCallManager::onVoiceCallsChanged()
+{
+ Q_D(VoiceCallManager);
+ QStringList nIds = d->interface->property("voiceCalls").toStringList();
+ QStringList oIds;
+
+ QStringList added;
+ QStringList removed;
+
+ // Map current call handlers to handler ids for easy indexing.
+ foreach(VoiceCallHandler *handler, d->voicecalls)
+ {
+ oIds.append(handler->handlerId());
+ }
+
+ // Index new handlers to be added.
+ foreach(QString nId, nIds)
+ {
+ if(!oIds.contains(nId)) added.append(nId);
+ }
+
+ // Index old handlers to be removed.
+ foreach(QString oId, oIds)
+ {
+ if(!nIds.contains(oId)) removed.append(oId);
+ }
+
+ // Remove handlers that need to be removed.
+ foreach(QString removeId, removed)
+ {
+ for (int i = 0; i < d->voicecalls.count(); ++i) {
+ VoiceCallHandler *handler = d->voicecalls.at(i);
+ if(handler->handlerId() == removeId)
+ {
+ handler->disconnect(this);
+ d->voicecalls.removeAt(i);
+ handler->deleteLater();
+ break;
+ }
+ }
+ }
+
+ // Add handlers that need to be added.
+ foreach(QString addId, added)
+ {
+ VoiceCallHandler *handler = new VoiceCallHandler(addId, this);
+ d->voicecalls.append(handler);
+ }
+
+ emit this->voiceCallsChanged();
+}
+
+void VoiceCallManager::onProvidersChanged()
+{
+ Q_D(VoiceCallManager);
+ d->providers.clear();
+ foreach(QString provider, d->interface->property("providers").toStringList())
+ {
+ QStringList parts = provider.split(':');
+ d->providers.insert(parts.first(), VoiceCallProviderData(parts.first(),
+ parts.last(),
+ parts.first()));
+ }
+
+ emit this->providersChanged();
+}
+
+void VoiceCallManager::onActiveVoiceCallChanged()
+{
+ Q_D(VoiceCallManager);
+ QString voiceCallId = d->interface->property("activeVoiceCall").toString();
+
+ if(d->voicecalls.count() == 0 || voiceCallId.isNull() || voiceCallId.isEmpty())
+ {
+ d->activeVoiceCall = NULL;
+ }
+ else
+ {
+ bool found = false;
+ d->activeVoiceCall = NULL;
+ foreach(VoiceCallHandler* handler, d->voicecalls)
+ {
+ if(handler->handlerId() == voiceCallId)
+ {
+ d->activeVoiceCall = handler;
+ found = true;
+ }
+ if(!found) d->activeVoiceCall = NULL;
+ }
+ }
+
+ emit this->activeVoiceCallChanged();
+}
+
+void VoiceCallManager::onPendingCallFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<bool> reply = *watcher;
+
+ if (reply.isError()) {
+ emit this->error(reply.error().message());
+ } else {
+ qCDebug(l) << QString("Received successful reply for member: ") + reply.reply().member();
+ }
+
+ watcher->deleteLater();
+}
+
+void VoiceCallManager::onPendingSilenceFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<> reply = *watcher;
+
+ if (reply.isError()) {
+ emit this->error(reply.error().message());
+ } else {
+ qCDebug(l) << QString("Received successful reply for member: ") + reply.reply().member();
+ }
+
+ watcher->deleteLater();
+}
diff --git a/rockworkd/platformintegration/sailfish/voicecallmanager.h b/rockworkd/platformintegration/sailfish/voicecallmanager.h
new file mode 100644
index 0000000..ec51230
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/voicecallmanager.h
@@ -0,0 +1,111 @@
+#ifndef VOICECALLMANAGER_H
+#define VOICECALLMANAGER_H
+
+#include "voicecallhandler.h"
+#include "settings.h"
+
+#include <QObject>
+#include <QDBusInterface>
+#include <QDBusPendingCallWatcher>
+#include <QLoggingCategory>
+
+class VoiceCallProviderData
+{
+public:
+ VoiceCallProviderData() {/*..*/}
+ VoiceCallProviderData(const QString &pId, const QString &pType, const QString &pLabel)
+ : id(pId), type(pType), label(pLabel) {/*...*/}
+
+ QString id;
+ QString type;
+ QString label;
+};
+
+typedef QHash<QString,VoiceCallProviderData> VoiceCallProviderHash;
+
+typedef QList<VoiceCallHandler*> VoiceCallHandlerList;
+
+class VoiceCallManager : public QObject
+{
+ Q_OBJECT
+ QLoggingCategory l;
+
+ Q_PROPERTY(QDBusInterface* interface READ interface)
+
+ Q_PROPERTY(VoiceCallHandlerList voiceCalls READ voiceCalls NOTIFY voiceCallsChanged)
+ Q_PROPERTY(VoiceCallProviderHash providers READ providers NOTIFY providersChanged)
+
+ Q_PROPERTY(QString defaultProviderId READ defaultProviderId NOTIFY defaultProviderChanged)
+
+ Q_PROPERTY(VoiceCallHandler* activeVoiceCall READ activeVoiceCall NOTIFY activeVoiceCallChanged)
+
+ Q_PROPERTY(QString audioMode READ audioMode WRITE setAudioMode NOTIFY audioModeChanged)
+ Q_PROPERTY(bool isAudioRouted READ isAudioRouted WRITE setAudioRouted NOTIFY audioRoutedChanged)
+ Q_PROPERTY(bool isMicrophoneMuted READ isMicrophoneMuted WRITE setMuteMicrophone NOTIFY microphoneMutedChanged)
+ Q_PROPERTY(bool isSpeakerMuted READ isSpeakerMuted WRITE setMuteSpeaker NOTIFY speakerMutedChanged)
+
+public:
+ explicit VoiceCallManager(Settings *settings, QObject *parent = 0);
+ ~VoiceCallManager();
+
+ QDBusInterface* interface() const;
+
+ VoiceCallHandlerList voiceCalls() const;
+ VoiceCallProviderHash providers() const;
+
+ QString defaultProviderId() const;
+
+ VoiceCallHandler* activeVoiceCall() const;
+
+ QString audioMode() const;
+ bool isAudioRouted() const;
+
+ bool isMicrophoneMuted() const;
+ bool isSpeakerMuted() const;
+
+Q_SIGNALS:
+ void error(const QString &message);
+
+ void providersChanged();
+ void voiceCallsChanged();
+
+ void defaultProviderChanged();
+
+ void activeVoiceCallChanged();
+
+ void audioModeChanged();
+ void audioRoutedChanged();
+ void microphoneMutedChanged();
+ void speakerMutedChanged();
+
+public Q_SLOTS:
+ void dial(const QString &providerId, const QString &msisdn);
+ void hangupAll();
+
+ void silenceRingtone();
+
+ bool setAudioMode(const QString &mode);
+ bool setAudioRouted(bool on);
+ bool setMuteMicrophone(bool on = true);
+ bool setMuteSpeaker(bool on = true);
+
+protected Q_SLOTS:
+ void initialize(bool notifyError = false);
+
+ void onProvidersChanged();
+ void onVoiceCallsChanged();
+ void onActiveVoiceCallChanged();
+
+ void onPendingCallFinished(QDBusPendingCallWatcher *watcher);
+ void onPendingSilenceFinished(QDBusPendingCallWatcher *watcher);
+
+private:
+ class VoiceCallManagerPrivate *d_ptr;
+
+ Settings *settings;
+
+ Q_DISABLE_COPY(VoiceCallManager)
+ Q_DECLARE_PRIVATE(VoiceCallManager)
+};
+
+#endif // VOICECALLMANAGER_H
diff --git a/rockworkd/rockworkd.pro b/rockworkd/rockworkd.pro
index a15d64d..888fefc 100644
--- a/rockworkd/rockworkd.pro
+++ b/rockworkd/rockworkd.pro
@@ -4,14 +4,12 @@ QT -= gui
include(../version.pri)
TARGET = rockpoold
-CONFIG += c++11
-#CONFIG -= app_bundle
-
-TEMPLATE = app
-INCLUDEPATH += /usr/lib/arm-linux-gnueabihf/glib-2.0/include /usr/lib/x86_64-linux-gnu/glib-2.0/include/ /usr/include/glib-2.0/
+CONFIG += c++11
+CONFIG += console
+CONFIG += link_pkgconfig
-INCLUDEPATH += /usr/include/telepathy-qt5/ /usr/include/quazip/
+INCLUDEPATH += /usr/include/telepathy-qt5/ $$[QT_HOST_PREFIX]/include/quazip/
LIBS += -lquazip -ltelepathy-qt5
SOURCES += main.cpp \
@@ -48,6 +46,8 @@ SOURCES += main.cpp \
# Platform integration part
platformintegration/sailfish/sailfishplatform.cpp \
platformintegration/sailfish/callchannelobserver.cpp \
+# platformintegration/sailfish/voicecallmanager.cpp \
+# platformintegration/sailfish/voicecallhandler.cpp \
libpebble/blobdb.cpp \
libpebble/timelineitem.cpp \
libpebble/notification.cpp \
@@ -99,6 +99,8 @@ HEADERS += \
# Platform integration part
platformintegration/sailfish/sailfishplatform.h \
platformintegration/sailfish/callchannelobserver.h \
+# platformintegration/sailfish/voicecallmanager.h \
+# platformintegration/sailfish/voicecallhandler.h \
libpebble/blobdb.h \
libpebble/timelineitem.h \
libpebble/notification.h \
@@ -124,19 +126,14 @@ testing: {
QT += qml quick
}
-libs.files = /usr/lib/arm-linux-gnueabihf/libQt5Bluetooth.so.5.4.1 \
- /usr/lib/arm-linux-gnueabihf/libQt5Bluetooth.so.5 \
- /usr/lib/arm-linux-gnueabihf/libquazip-qt5.so.1.0.0 \
- /usr/lib/arm-linux-gnueabihf/libquazip-qt5.so.1
-libs.path = /usr/
-INSTALLS += libs
+INSTALLS += target systemd
systemd.files = $${TARGET}.service
systemd.path = /usr/lib/systemd/user
# Default rules for deployment.
target.path = /usr/bin
-INSTALLS+=target
RESOURCES += \
libpebble/jskit/jsfiles.qrc
+