[Telepathy-commits] [telepathy-qt4/master] ConnectionManager: start to implement introspection of protocols/params

Simon McVittie simon.mcvittie at collabora.co.uk
Fri Dec 5 10:11:11 PST 2008


---
 TelepathyQt4/cli-connection-manager.cpp |  154 ++++++++++++++++++++++++++++++-
 TelepathyQt4/cli-connection-manager.h   |   33 ++++++-
 2 files changed, 180 insertions(+), 7 deletions(-)

diff --git a/TelepathyQt4/cli-connection-manager.cpp b/TelepathyQt4/cli-connection-manager.cpp
index a0aca31..165760b 100644
--- a/TelepathyQt4/cli-connection-manager.cpp
+++ b/TelepathyQt4/cli-connection-manager.cpp
@@ -21,7 +21,13 @@
 
 #include "cli-connection-manager.h"
 
+#include <QtCore/QQueue>
+#include <QtCore/QStringList>
+#include <QtCore/QTimer>
+
+#include <TelepathyQt4/Client/DBus>
 #include <TelepathyQt4/Constants>
+#include <TelepathyQt4/Types>
 
 #include "TelepathyQt4/debug-internal.hpp"
 
@@ -34,8 +40,13 @@ namespace Client
 struct ConnectionManager::Private
 {
     ConnectionManager& parent;
-
     ConnectionManagerInterface* baseInterface;
+    bool ready;
+    QQueue<void (Private::*)()> introspectQueue;
+    QQueue<QString> protocolQueue;
+
+    QStringList interfaces;
+    QStringList protocols;
 
     static inline QString makeBusName(const QString& name)
     {
@@ -49,12 +60,62 @@ struct ConnectionManager::Private
                 TELEPATHY_CONNECTION_MANAGER_OBJECT_PATH_BASE).append(name);
     }
 
-    inline Private(ConnectionManager& parent)
+    void continueIntrospection()
+    {
+        if (!ready) {
+            if (introspectQueue.isEmpty()) {
+                // TODO: signal ready
+                debug() << "ConnectionManager is ready";
+            } else {
+                (this->*introspectQueue.dequeue())();
+            }
+        }
+    }
+
+    void callGetAll()
+    {
+        debug() << "Calling Properties::GetAll(ConnectionManager)";
+        QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
+                parent.propertiesInterface()->GetAll(
+                    TELEPATHY_INTERFACE_CONNECTION_MANAGER), &parent);
+        parent.connect(watcher,
+                SIGNAL(finished(QDBusPendingCallWatcher*)),
+                SLOT(onGetAllConnectionManagerReturn(QDBusPendingCallWatcher*)));
+    }
+
+    void callGetParameters()
+    {
+        QString protocol = protocolQueue.dequeue();
+        debug() << "Calling ConnectionManager::GetParameters(" <<
+            protocol << ")";
+        QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
+                baseInterface->GetParameters(protocol), &parent);
+        parent.connect(watcher,
+                SIGNAL(finished(QDBusPendingCallWatcher*)),
+                SLOT(onGetParametersReturn(QDBusPendingCallWatcher*)));
+    }
+
+    void callListProtocols()
+    {
+        debug() << "Calling ConnectionManager::ListProtocols";
+        QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
+                baseInterface->ListProtocols(), &parent);
+        parent.connect(watcher,
+                SIGNAL(finished(QDBusPendingCallWatcher*)),
+                SLOT(onListProtocolsReturn(QDBusPendingCallWatcher*)));
+    }
+
+    Private(ConnectionManager& parent)
         : parent(parent),
           baseInterface(new ConnectionManagerInterface(parent.dbusConnection(),
-                      parent.busName(), parent.objectPath(), &parent))
+                      parent.busName(), parent.objectPath(), &parent)),
+          ready(false)
     {
         debug() << "Creating new ConnectionManager:" << parent.busName();
+
+        introspectQueue.enqueue(&Private::callGetAll);
+        introspectQueue.enqueue(&Private::callListProtocols);
+        QTimer::singleShot(0, &parent, SLOT(onStartIntrospection()));
     }
 };
 
@@ -83,12 +144,99 @@ ConnectionManager::~ConnectionManager()
 }
 
 
+QStringList ConnectionManager::interfaces() const
+{
+    return mPriv->interfaces;
+}
+
+
+QStringList ConnectionManager::supportedProtocols() const
+{
+    return mPriv->protocols;
+}
+
+
 ConnectionManagerInterface* ConnectionManager::baseInterface() const
 {
     return mPriv->baseInterface;
 }
 
 
+void ConnectionManager::onGetAllConnectionManagerReturn(
+        QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QVariantMap> reply = *watcher;
+    QVariantMap props;
+
+    if (!reply.isError()) {
+        debug() << "Got reply to Properties.GetAll(ConnectionManager)";
+        props = reply.value();
+    } else {
+        warning().nospace() <<
+            "Properties.GetAll(ConnectionManager) failed: " <<
+            reply.error().name() << ": " << reply.error().message();
+    }
+
+    // If Interfaces is not supported, the spec says to assume it's
+    // empty, so keep the empty list mPriv was initialized with
+    if (props.contains("Interfaces")) {
+        mPriv->interfaces = qdbus_cast<QStringList>(props["Interfaces"]);
+    }
+    mPriv->continueIntrospection();
+}
+
+
+void ConnectionManager::onListProtocolsReturn(
+        QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QStringList> reply = *watcher;
+    QStringList protocols;
+
+    if (!reply.isError()) {
+        debug() << "Got reply to ConnectionManager.ListProtocols";
+        protocols = reply.value();
+    } else {
+        warning().nospace() <<
+            "ConnectionManager.ListProtocols failed: " <<
+            reply.error().name() << ": " << reply.error().message();
+    }
+
+    mPriv->protocols = protocols;
+    Q_FOREACH (const QString& protocol, protocols) {
+        mPriv->protocolQueue.enqueue(protocol);
+        mPriv->introspectQueue.enqueue(&Private::callGetParameters);
+    }
+    mPriv->continueIntrospection();
+}
+
+
+void ConnectionManager::onGetParametersReturn(
+        QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<ParamSpecList> reply = *watcher;
+    ParamSpecList parameters;
+
+    if (!reply.isError()) {
+        debug() << "Got reply to ConnectionManager.GetParameters";
+        parameters = reply.value();
+    } else {
+        warning().nospace() <<
+            "ConnectionManager.GetParameters failed: " <<
+            reply.error().name() << ": " << reply.error().message();
+    }
+
+    Q_FOREACH (const ParamSpec& spec, parameters) {
+        debug() << "Parameter" << spec.name << "has flags" << spec.flags
+            << "and signature" << spec.signature;
+    }
+    mPriv->continueIntrospection();
+}
+
+void ConnectionManager::onStartIntrospection()
+{
+    mPriv->continueIntrospection();
+}
+
 } // Telepathy::Client
 } // Telepathy
 
diff --git a/TelepathyQt4/cli-connection-manager.h b/TelepathyQt4/cli-connection-manager.h
index 9484534..64f7452 100644
--- a/TelepathyQt4/cli-connection-manager.h
+++ b/TelepathyQt4/cli-connection-manager.h
@@ -42,6 +42,7 @@
 
 #include <TelepathyQt4/_gen/cli-connection-manager.h>
 
+#include <TelepathyQt4/Client/DBus>
 #include <TelepathyQt4/Client/DBusProxy>
 #include <TelepathyQt4/Client/OptionalInterfaceFactory>
 
@@ -68,6 +69,11 @@ class ConnectionManager : public StatelessDBusProxy,
 {
     Q_OBJECT
 
+private:
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+
 public:
     ConnectionManager(const QString& name, QObject* parent = 0);
     ConnectionManager(const QDBusConnection& bus,
@@ -75,6 +81,24 @@ public:
 
     virtual ~ConnectionManager();
 
+    QStringList interfaces() const;
+
+    QStringList supportedProtocols() const;
+
+    // TODO: add some sort of access to protocols' parameters etc.
+
+    /**
+     * Convenience function for getting a Properties interface proxy. The
+     * Properties interface is not necessarily reported by the services, so a
+     * <code>check</code> parameter is not provided, and the interface is
+     * always assumed to be present.
+     */
+    inline DBus::PropertiesInterface* propertiesInterface() const
+    {
+        return OptionalInterfaceFactory::interface<DBus::PropertiesInterface>(
+                *baseInterface());
+    }
+
 protected:
     /**
      * Get the ConnectionManagerInterface for this ConnectionManager. This
@@ -87,10 +111,11 @@ protected:
      */
     ConnectionManagerInterface* baseInterface() const;
 
-private:
-    struct Private;
-    friend struct Private;
-    Private *mPriv;
+private Q_SLOTS:
+    void onGetParametersReturn(QDBusPendingCallWatcher*);
+    void onListProtocolsReturn(QDBusPendingCallWatcher*);
+    void onGetAllConnectionManagerReturn(QDBusPendingCallWatcher*);
+    void onStartIntrospection();
 };
 
 
-- 
1.5.6.5




More information about the Telepathy-commits mailing list