[Telepathy-commits] [telepathy-qt4/master] Connection: Added createChannel/ensureChannel.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Sun Jan 25 14:01:42 PST 2009
---
TelepathyQt4/Client/connection.cpp | 115 +++++++++++++++++++++++++++++--
TelepathyQt4/Client/connection.h | 11 +++
TelepathyQt4/Client/pending-channel.cpp | 92 ++++++++++++++++++++++++-
TelepathyQt4/Client/pending-channel.h | 6 ++-
4 files changed, 217 insertions(+), 7 deletions(-)
diff --git a/TelepathyQt4/Client/connection.cpp b/TelepathyQt4/Client/connection.cpp
index 61aba19..93882b4 100644
--- a/TelepathyQt4/Client/connection.cpp
+++ b/TelepathyQt4/Client/connection.cpp
@@ -28,6 +28,7 @@
#include "TelepathyQt4/debug-internal.h"
#include <TelepathyQt4/Client/PendingChannel>
+#include <TelepathyQt4/Client/PendingFailure>
#include <TelepathyQt4/Client/PendingHandles>
#include <TelepathyQt4/Client/PendingVoidMethodCall>
@@ -1058,18 +1059,122 @@ ConnectionInterface *Connection::baseInterface() const
PendingChannel *Connection::requestChannel(const QString &channelType,
uint handleType, uint handle)
{
+ if (mPriv->readiness != Private::ReadinessFull) {
+ warning() << "Calling requestChannel with connection not yet connected";
+ return new PendingChannel(this, TELEPATHY_ERROR_NOT_AVAILABLE,
+ "Connection not yet connected");
+ }
+
debug() << "Requesting a Channel with type" << channelType
<< "and handle" << handle << "of type" << handleType;
PendingChannel *channel =
new PendingChannel(this, channelType, handleType, handle);
- QDBusPendingCallWatcher *watcher =
- new QDBusPendingCallWatcher(mPriv->baseInterface->RequestChannel(
- channelType, handleType, handle, true), channel);
- channel->connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)),
- SLOT(onCallFinished(QDBusPendingCallWatcher *)));
+ return channel;
+}
+
+/**
+ * Asynchronously creates a channel satisfying the given request.
+ *
+ * The request MUST contain the following keys:
+ * org.freedesktop.Telepathy.Account.ChannelType
+ * org.freedesktop.Telepathy.Account.TargetHandleType
+ *
+ * Upon completion, the reply to the request can be retrieved through the
+ * returned PendingChannel object. The object also provides access to the
+ * parameters with which the call was made and a signal to connect to get
+ * notification of the request finishing processing. See the documentation
+ * for that class for more info.
+ *
+ * The returned PendingChannel object should be freed using
+ * its QObject::deleteLater() method after it is no longer used. However,
+ * all PendingChannel objects resulting from requests to a particular
+ * Connection will be freed when the Connection itself is freed. Conversely,
+ * this means that the PendingChannel object should not be used after the
+ * Connection is destroyed.
+ *
+ * \sa PendingChannel
+ *
+ * \param request A dictionary containing the desirable properties.
+ * \return Pointer to a newly constructed PendingChannel object, tracking
+ * the progress of the request.
+ */
+PendingChannel *Connection::createChannel(const QVariantMap &request)
+{
+ if (mPriv->readiness != Private::ReadinessFull) {
+ warning() << "Calling createChannel with connection not yet connected";
+ return new PendingChannel(this, TELEPATHY_ERROR_NOT_AVAILABLE,
+ "Connection not yet connected");
+ }
+
+ if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_REQUESTS)) {
+ warning() << "Requests interface is not support by this connection";
+ return new PendingChannel(this, TELEPATHY_ERROR_NOT_IMPLEMENTED,
+ "Connection does not support Requests Interface");
+ }
+
+ if (!request.contains(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")) ||
+ !request.contains(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"))) {
+ return new PendingChannel(this, TELEPATHY_ERROR_INVALID_ARGUMENT,
+ "Invalid 'request' argument");
+ }
+
+ debug() << "Creating a Channel";
+ PendingChannel *channel =
+ new PendingChannel(this, request, true);
+ return channel;
+}
+
+/**
+ * Asynchronously ensures a channel exists satisfying the given request.
+ *
+ * The request MUST contain the following keys:
+ * org.freedesktop.Telepathy.Account.ChannelType
+ * org.freedesktop.Telepathy.Account.TargetHandleType
+ *
+ * Upon completion, the reply to the request can be retrieved through the
+ * returned PendingChannel object. The object also provides access to the
+ * parameters with which the call was made and a signal to connect to get
+ * notification of the request finishing processing. See the documentation
+ * for that class for more info.
+ *
+ * The returned PendingChannel object should be freed using
+ * its QObject::deleteLater() method after it is no longer used. However,
+ * all PendingChannel objects resulting from requests to a particular
+ * Connection will be freed when the Connection itself is freed. Conversely,
+ * this means that the PendingChannel object should not be used after the
+ * Connection is destroyed.
+ *
+ * \sa PendingChannel
+ *
+ * \param request A dictionary containing the desirable properties.
+ * \return Pointer to a newly constructed PendingChannel object, tracking
+ * the progress of the request.
+ */
+PendingChannel *Connection::ensureChannel(const QVariantMap &request)
+{
+ if (mPriv->readiness != Private::ReadinessFull) {
+ warning() << "Calling ensureChannel with connection not yet connected";
+ return new PendingChannel(this, TELEPATHY_ERROR_NOT_AVAILABLE,
+ "Connection not yet connected");
+ }
+
+ if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_REQUESTS)) {
+ warning() << "Requests interface is not support by this connection";
+ return new PendingChannel(this, TELEPATHY_ERROR_NOT_IMPLEMENTED,
+ "Connection does not support Requests Interface");
+ }
+
+ if (!request.contains(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")) ||
+ !request.contains(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"))) {
+ return new PendingChannel(this, TELEPATHY_ERROR_INVALID_ARGUMENT,
+ "Invalid 'request' argument");
+ }
+ debug() << "Creating a Channel";
+ PendingChannel *channel =
+ new PendingChannel(this, request, false);
return channel;
}
diff --git a/TelepathyQt4/Client/connection.h b/TelepathyQt4/Client/connection.h
index 8950085..c58cfca 100644
--- a/TelepathyQt4/Client/connection.h
+++ b/TelepathyQt4/Client/connection.h
@@ -130,6 +130,12 @@ public:
return optionalInterface<ConnectionInterfaceSimplePresenceInterface>(check);
}
+ inline ConnectionInterfaceRequestsInterface *requestsInterface(
+ InterfaceSupportedChecking check = CheckInterfaceSupported) const
+ {
+ return optionalInterface<ConnectionInterfaceRequestsInterface>(check);
+ }
+
inline DBus::PropertiesInterface *propertiesInterface() const
{
return optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck);
@@ -138,6 +144,10 @@ public:
PendingChannel *requestChannel(const QString &channelType,
uint handleType, uint handle);
+ PendingChannel *createChannel(const QVariantMap &request);
+
+ PendingChannel *ensureChannel(const QVariantMap &request);
+
PendingOperation *requestConnect();
PendingOperation *requestDisconnect();
@@ -175,6 +185,7 @@ private:
struct Private;
friend struct Private;
+ friend class PendingChannel;
friend class PendingHandles;
friend class ReferencedHandles;
Private *mPriv;
diff --git a/TelepathyQt4/Client/pending-channel.cpp b/TelepathyQt4/Client/pending-channel.cpp
index 16221d3..2a1d253 100644
--- a/TelepathyQt4/Client/pending-channel.cpp
+++ b/TelepathyQt4/Client/pending-channel.cpp
@@ -40,12 +40,54 @@ struct PendingChannel::Private
QDBusObjectPath objectPath;
};
+PendingChannel::PendingChannel(Connection* connection, const QString& errorName,
+ const QString& errorMessage)
+ : PendingOperation(connection),
+ mPriv(new Private)
+{
+ mPriv->handleType = 0;
+ mPriv->handle = 0;
+
+ setFinishedWithError(errorName, errorMessage);
+}
+
PendingChannel::PendingChannel(Connection* connection, const QString& channelType, uint handleType, uint handle)
: PendingOperation(connection), mPriv(new Private)
{
mPriv->channelType = channelType;
mPriv->handleType = handleType;
mPriv->handle = handle;
+
+ QDBusPendingCallWatcher *watcher =
+ new QDBusPendingCallWatcher(connection->baseInterface()->RequestChannel(
+ channelType, handleType, handle, true), this);
+ connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(onCallRequestChannelFinished(QDBusPendingCallWatcher *)));
+}
+
+PendingChannel::PendingChannel(Connection* connection, const QVariantMap& request, bool create)
+ : PendingOperation(connection),
+ mPriv(new Private)
+{
+ mPriv->channelType = request.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString();
+ mPriv->handleType = request.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType")).toUInt();
+ mPriv->handle = request.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandle")).toUInt();
+
+ if (create) {
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
+ connection->requestsInterface()->CreateChannel(request), this);
+ connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(onCallCreateChannelFinished(QDBusPendingCallWatcher *)));
+ }
+ else {
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
+ connection->requestsInterface()->EnsureChannel(request), this);
+ connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(onCallEnsureChannelFinished(QDBusPendingCallWatcher *)));
+ }
}
PendingChannel::~PendingChannel()
@@ -90,7 +132,7 @@ Channel* PendingChannel::channel(QObject* parent) const
return channel;
}
-void PendingChannel::onCallFinished(QDBusPendingCallWatcher* watcher)
+void PendingChannel::onCallRequestChannelFinished(QDBusPendingCallWatcher* watcher)
{
QDBusPendingReply<QDBusObjectPath> reply = *watcher;
@@ -108,5 +150,53 @@ void PendingChannel::onCallFinished(QDBusPendingCallWatcher* watcher)
watcher->deleteLater();
}
+void PendingChannel::onCallCreateChannelFinished(QDBusPendingCallWatcher* watcher)
+{
+ QDBusPendingReply<QDBusObjectPath, QVariantMap> reply = *watcher;
+
+ debug() << "Received reply to RequestChannel";
+
+ if (!reply.isError()) {
+ mPriv->objectPath = reply.argumentAt<0>();
+ debug() << " Success: object path" << mPriv->objectPath.path();
+
+ QVariantMap map = reply.argumentAt<1>();
+ mPriv->channelType = map.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString();
+ mPriv->handleType = map.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType")).toUInt();
+ mPriv->handle = map.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandle")).toUInt();
+
+ setFinished();
+ } else {
+ debug().nospace() << " Failure: error " << reply.error().name() << ": " << reply.error().message();
+ setFinishedWithError(reply.error());
+ }
+
+ watcher->deleteLater();
+}
+
+void PendingChannel::onCallEnsureChannelFinished(QDBusPendingCallWatcher* watcher)
+{
+ QDBusPendingReply<bool, QDBusObjectPath, QVariantMap> reply = *watcher;
+
+ debug() << "Received reply to RequestChannel";
+
+ if (!reply.isError()) {
+ mPriv->objectPath = reply.argumentAt<1>();
+ debug() << " Success: object path" << mPriv->objectPath.path();
+
+ QVariantMap map = reply.argumentAt<2>();
+ mPriv->channelType = map.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString();
+ mPriv->handleType = map.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType")).toUInt();
+ mPriv->handle = map.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandle")).toUInt();
+
+ setFinished();
+ } else {
+ debug().nospace() << " Failure: error " << reply.error().name() << ": " << reply.error().message();
+ setFinishedWithError(reply.error());
+ }
+
+ watcher->deleteLater();
+}
+
} // Telepathy::Client
} // Telepathy
diff --git a/TelepathyQt4/Client/pending-channel.h b/TelepathyQt4/Client/pending-channel.h
index 6e93f8d..3956388 100644
--- a/TelepathyQt4/Client/pending-channel.h
+++ b/TelepathyQt4/Client/pending-channel.h
@@ -122,12 +122,16 @@ public:
Channel* channel(QObject* parent = 0) const;
private Q_SLOTS:
- void onCallFinished(QDBusPendingCallWatcher* watcher);
+ void onCallRequestChannelFinished(QDBusPendingCallWatcher* watcher);
+ void onCallCreateChannelFinished(QDBusPendingCallWatcher* watcher);
+ void onCallEnsureChannelFinished(QDBusPendingCallWatcher* watcher);
private:
friend class Connection;
+ PendingChannel(Connection* connection, const QString& errorName, const QString& errorMessage);
PendingChannel(Connection* connection, const QString& type, uint handleType, uint handle);
+ PendingChannel(Connection* connection, const QVariantMap& request, bool create);
struct Private;
friend struct Private;
--
1.5.6.5
More information about the Telepathy-commits
mailing list