[Telepathy-commits] [telepathy-qt4/master] ConnectionManager: Use ReadinessHelper class.

Andre Moreira Magalhaes (andrunko) andre.magalhaes at collabora.co.uk
Wed Mar 4 07:41:02 PST 2009


---
 TelepathyQt4/Client/account.cpp                   |    1 -
 TelepathyQt4/Client/connection-manager-internal.h |   28 ++-
 TelepathyQt4/Client/connection-manager.cpp        |  235 ++++++++++-----------
 TelepathyQt4/Client/connection-manager.h          |   22 +--
 tests/dbus/cm-basics.cpp                          |    2 +-
 tests/pinocchio/cm-basics.cpp                     |    2 +-
 tests/pinocchio/conn-basics.cpp                   |    1 -
 7 files changed, 140 insertions(+), 151 deletions(-)

diff --git a/TelepathyQt4/Client/account.cpp b/TelepathyQt4/Client/account.cpp
index 392af3e..afd68e7 100644
--- a/TelepathyQt4/Client/account.cpp
+++ b/TelepathyQt4/Client/account.cpp
@@ -32,7 +32,6 @@
 #include <TelepathyQt4/Client/ConnectionManager>
 #include <TelepathyQt4/Client/PendingFailure>
 #include <TelepathyQt4/Client/PendingReady>
-#include <TelepathyQt4/Client/PendingReadyConnectionManager>
 #include <TelepathyQt4/Client/PendingVoidMethodCall>
 #include <TelepathyQt4/Client/ReadinessHelper>
 #include <TelepathyQt4/Constants>
diff --git a/TelepathyQt4/Client/connection-manager-internal.h b/TelepathyQt4/Client/connection-manager-internal.h
index 97e2d00..d205455 100644
--- a/TelepathyQt4/Client/connection-manager-internal.h
+++ b/TelepathyQt4/Client/connection-manager-internal.h
@@ -36,13 +36,19 @@ namespace Client
 
 class ConnectionManager;
 class ConnectionManagerInterface;
-class PendingReadyConnectionManager;
+class ReadinessHelper;
 
 struct ConnectionManager::Private
 {
-    Private(const QString &name, ConnectionManager *parent);
+    Private(ConnectionManager *parent, const QString &name);
     ~Private();
 
+    bool parseConfigFile();
+
+    static void introspectMain(Private *self);
+    void introspectProtocols();
+    void introspectParameters();
+
     static QString makeBusName(const QString &name);
     static QString makeObjectPath(const QString &name);
 
@@ -50,16 +56,20 @@ struct ConnectionManager::Private
 
     class PendingNames;
 
-    ConnectionManagerInterface *baseInterface;
+    // Public object
+    ConnectionManager *parent;
+
     QString name;
-    bool ready;
-    QQueue<void (ConnectionManager::*)()> introspectQueue;
-    QQueue<QString> getParametersQueue;
-    QQueue<QString> protocolQueue;
+
+    // Instance of generated interface class
+    ConnectionManagerInterface *baseInterface;
+
+    ReadinessHelper *readinessHelper;
+
+    // Introspection
     QStringList interfaces;
+    QQueue<QString> parametersQueue;
     ProtocolInfoList protocols;
-    PendingReadyConnectionManager *pendingReady;
-    ConnectionManager::Features features;
 };
 
 class ConnectionManager::Private::PendingNames : public PendingStringList
diff --git a/TelepathyQt4/Client/connection-manager.cpp b/TelepathyQt4/Client/connection-manager.cpp
index c51080e..b527431 100644
--- a/TelepathyQt4/Client/connection-manager.cpp
+++ b/TelepathyQt4/Client/connection-manager.cpp
@@ -31,7 +31,8 @@
 
 #include <TelepathyQt4/Client/DBus>
 #include <TelepathyQt4/Client/PendingConnection>
-#include <TelepathyQt4/Client/PendingReadyConnectionManager>
+#include <TelepathyQt4/Client/PendingReady>
+#include <TelepathyQt4/Client/ReadinessHelper>
 #include <TelepathyQt4/Constants>
 #include <TelepathyQt4/ManagerFile>
 #include <TelepathyQt4/Types>
@@ -281,15 +282,27 @@ void ConnectionManager::Private::PendingNames::parseResult(const QStringList &na
     }
 }
 
-ConnectionManager::Private::Private(const QString &name, ConnectionManager *parent)
-    : baseInterface(new ConnectionManagerInterface(parent->dbusConnection(),
-                            parent->busName(), parent->objectPath(), parent)),
+ConnectionManager::Private::Private(ConnectionManager *parent, const QString &name)
+    : parent(parent),
       name(name),
-      ready(false),
-      pendingReady(0),
-      features(0)
+      baseInterface(new ConnectionManagerInterface(parent->dbusConnection(),
+                    parent->busName(), parent->objectPath(), parent))
 {
     debug() << "Creating new ConnectionManager:" << parent->busName();
+
+    QMap<uint, ReadinessHelper::Introspectable> introspectables;
+
+    // As ConnectionManager does not have predefined statuses let's simulate one (0)
+    ReadinessHelper::Introspectable introspectableCore(
+        QSet<uint>() << 0,                                           // makesSenseForStatuses
+        QSet<uint>(),                                                // dependsOnFeatures
+        QStringList(),                                               // dependsOnInterfaces
+        (ReadinessHelper::IntrospectFunc) &Private::introspectMain,
+        this);
+    introspectables[FeatureCore] = introspectableCore;
+
+    readinessHelper = new ReadinessHelper(parent, 0 /* status */,
+            introspectables, parent);
 }
 
 ConnectionManager::Private::~Private()
@@ -346,12 +359,8 @@ ConnectionManager::ConnectionManager(const QString &name, QObject *parent)
             Private::makeBusName(name), Private::makeObjectPath(name),
             parent),
       OptionalInterfaceFactory<ConnectionManager>(this),
-      mPriv(new Private(name, this))
+      mPriv(new Private(this, name))
 {
-    if (isValid()) {
-        mPriv->introspectQueue.enqueue(&ConnectionManager::callReadConfig);
-        QTimer::singleShot(0, this, SLOT(continueIntrospection()));
-    }
 }
 
 /**
@@ -366,12 +375,8 @@ ConnectionManager::ConnectionManager(const QDBusConnection &bus,
     : StatelessDBusProxy(bus, Private::makeBusName(name),
             Private::makeObjectPath(name), parent),
       OptionalInterfaceFactory<ConnectionManager>(this),
-      mPriv(new Private(name, this))
+      mPriv(new Private(this, name))
 {
-    if (isValid()) {
-        mPriv->introspectQueue.enqueue(&ConnectionManager::callReadConfig);
-        QTimer::singleShot(0, this, SLOT(continueIntrospection()));
-    }
 }
 
 /**
@@ -460,12 +465,12 @@ PendingConnection *ConnectionManager::requestConnection(const QString &protocol,
  * until the object is ready. To wait for the object to be ready, call
  * becomeReady() and connect to the finished signal on the result.
  *
+ * \param features The features which should be tested
  * \return \c true if the object has finished initial setup.
  */
-bool ConnectionManager::isReady(Features features) const
+bool ConnectionManager::isReady(const QSet<uint> &features) const
 {
-    return mPriv->ready
-        && ((mPriv->features & features) == features);
+    return mPriv->readinessHelper->isReady(features);
 }
 
 /**
@@ -473,31 +478,17 @@ bool ConnectionManager::isReady(Features features) const
  * its initial setup, or will fail if a fatal error occurs during this
  * initial setup.
  *
- * \return A PendingReadyConnectionManager object which will emit finished
- *         when this object has finished or failed its initial setup.
+ * If an empty set is used FeatureCore will be considered as the requested
+ * feature.
+ *
+ * \param requestedFeatures The features which should be enabled
+ * \return A PendingReady object which will emit finished
+ *         when this object has finished or failed initial setup for basic
+ *         functionality plus the given features
  */
-PendingReadyConnectionManager *ConnectionManager::becomeReady(Features requestedFeatures)
-{
-    if (!isValid()) {
-        PendingReadyConnectionManager *operation =
-            new PendingReadyConnectionManager(requestedFeatures, this);
-        operation->setFinishedWithError(TELEPATHY_ERROR_NOT_AVAILABLE,
-                "ConnectionManager is invalid");
-        return operation;
-    }
-
-    if (isReady(requestedFeatures)) {
-        PendingReadyConnectionManager *operation =
-            new PendingReadyConnectionManager(requestedFeatures, this);
-        operation->setFinished();
-        return operation;
-    }
-
-    if (!mPriv->pendingReady) {
-        mPriv->pendingReady =
-            new PendingReadyConnectionManager(requestedFeatures, this);
-    }
-    return mPriv->pendingReady;
+PendingReady *ConnectionManager::becomeReady(const QSet<uint> &requestedFeatures)
+{
+    return mPriv->readinessHelper->becomeReady(requestedFeatures);
 }
 
 /**
@@ -529,17 +520,16 @@ ConnectionManagerInterface *ConnectionManager::baseInterface() const
 }
 
 /**** Private ****/
-bool ConnectionManager::checkConfigFile()
+bool ConnectionManager::Private::parseConfigFile()
 {
-    ManagerFile f(mPriv->name);
+    ManagerFile f(name);
     if (!f.isValid()) {
         return false;
     }
 
     Q_FOREACH (QString protocol, f.protocols()) {
-        ProtocolInfo *info = new ProtocolInfo(mPriv->name,
-                                              protocol);
-        mPriv->protocols.append(info);
+        ProtocolInfo *info = new ProtocolInfo(name, protocol);
+        protocols.append(info);
 
         Q_FOREACH (ParamSpec spec, f.parameters(protocol)) {
             info->addParameter(spec);
@@ -547,7 +537,7 @@ bool ConnectionManager::checkConfigFile()
     }
 
 #if 0
-    Q_FOREACH (ProtocolInfo *info, mPriv->protocols) {
+    Q_FOREACH (ProtocolInfo *info, protocols) {
         qDebug() << "protocol name   :" << info->name();
         qDebug() << "protocol cn name:" << info->cmName();
         Q_FOREACH (ProtocolParameter *param, info->parameters()) {
@@ -562,53 +552,51 @@ bool ConnectionManager::checkConfigFile()
     return true;
 }
 
-void ConnectionManager::callReadConfig()
+void ConnectionManager::Private::introspectMain(ConnectionManager::Private *self)
 {
-    if (!checkConfigFile()) {
-        warning() << "error parsing config file for connection manager"
-                  << mPriv->name;
-        mPriv->introspectQueue.enqueue(&ConnectionManager::callGetAll);
-        mPriv->introspectQueue.enqueue(&ConnectionManager::callListProtocols);
+    if (self->parseConfigFile()) {
+        self->readinessHelper->setIntrospectCompleted(FeatureCore, true);
+        return;
     }
 
-    continueIntrospection();
-}
+    warning() << "Error parsing config file for connection manager"
+        << self->name << "- introspecting";
+
+    DBus::PropertiesInterface *properties = self->parent->propertiesInterface();
+    Q_ASSERT(properties != 0);
 
-void ConnectionManager::callGetAll()
-{
     debug() << "Calling Properties::GetAll(ConnectionManager)";
     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
-            propertiesInterface()->GetAll(
-                TELEPATHY_INTERFACE_CONNECTION_MANAGER), this);
-    connect(watcher,
+            properties->GetAll(
+                TELEPATHY_INTERFACE_CONNECTION_MANAGER), self->parent);
+    self->parent->connect(watcher,
             SIGNAL(finished(QDBusPendingCallWatcher *)),
-            SLOT(onGetAllConnectionManagerReturn(QDBusPendingCallWatcher *)));
+            SLOT(gotMainProperties(QDBusPendingCallWatcher *)));
 }
 
-void ConnectionManager::callGetParameters()
+void ConnectionManager::Private::introspectProtocols()
 {
-    QString protocol = mPriv->getParametersQueue.dequeue();
-    mPriv->protocolQueue.enqueue(protocol);
-    debug() << "Calling ConnectionManager::GetParameters(" << protocol << ")";
+    debug() << "Calling ConnectionManager::ListProtocols";
     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
-            mPriv->baseInterface->GetParameters(protocol), this);
-    connect(watcher,
+            baseInterface->ListProtocols(), parent);
+    parent->connect(watcher,
             SIGNAL(finished(QDBusPendingCallWatcher *)),
-            SLOT(onGetParametersReturn(QDBusPendingCallWatcher *)));
+            SLOT(gotProtocols(QDBusPendingCallWatcher *)));
 }
 
-void ConnectionManager::callListProtocols()
+void ConnectionManager::Private::introspectParameters()
 {
-    debug() << "Calling ConnectionManager::ListProtocols";
-    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
-            mPriv->baseInterface->ListProtocols(), this);
-    connect(watcher,
-            SIGNAL(finished(QDBusPendingCallWatcher *)),
-            SLOT(onListProtocolsReturn(QDBusPendingCallWatcher *)));
+    foreach (const QString &protocolName, parametersQueue) {
+        debug() << "Calling ConnectionManager::GetParameters(" << protocolName << ")";
+        QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
+                baseInterface->GetParameters(protocolName), parent);
+        parent->connect(watcher,
+                SIGNAL(finished(QDBusPendingCallWatcher *)),
+                SLOT(gotParameters(QDBusPendingCallWatcher *)));
+    }
 }
 
-void ConnectionManager::onGetAllConnectionManagerReturn(
-        QDBusPendingCallWatcher *watcher)
+void ConnectionManager::gotMainProperties(QDBusPendingCallWatcher *watcher)
 {
     QDBusPendingReply<QVariantMap> reply = *watcher;
     QVariantMap props;
@@ -621,6 +609,7 @@ void ConnectionManager::onGetAllConnectionManagerReturn(
         // empty, so keep the empty list mPriv was initialized with
         if (props.contains("Interfaces")) {
             mPriv->interfaces = qdbus_cast<QStringList>(props["Interfaces"]);
+            mPriv->readinessHelper->setInterfaces(mPriv->interfaces);
         }
     } else {
         warning().nospace() <<
@@ -628,13 +617,12 @@ void ConnectionManager::onGetAllConnectionManagerReturn(
             reply.error().name() << ": " << reply.error().message();
     }
 
-    continueIntrospection();
+    mPriv->introspectProtocols();
 
     watcher->deleteLater();
 }
 
-void ConnectionManager::onListProtocolsReturn(
-        QDBusPendingCallWatcher *watcher)
+void ConnectionManager::gotProtocols(QDBusPendingCallWatcher *watcher)
 {
     QDBusPendingReply<QStringList> reply = *watcher;
     QStringList protocolsNames;
@@ -642,70 +630,67 @@ void ConnectionManager::onListProtocolsReturn(
     if (!reply.isError()) {
         debug() << "Got reply to ConnectionManager.ListProtocols";
         protocolsNames = reply.value();
+
+        Q_FOREACH (const QString &protocolName, protocolsNames) {
+            mPriv->protocols.append(new ProtocolInfo(mPriv->name,
+                        protocolName));
+            mPriv->parametersQueue.enqueue(protocolName);
+        }
+
+        mPriv->introspectParameters();
     } else {
+        // TODO should we fail here, or finish silently?
+        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
+
         warning().nospace() <<
             "ConnectionManager.ListProtocols failed: " <<
             reply.error().name() << ": " << reply.error().message();
     }
 
-    Q_FOREACH (const QString &protocolName, protocolsNames) {
-        mPriv->protocols.append(new ProtocolInfo(mPriv->name,
-                    protocolName));
-
-        mPriv->getParametersQueue.enqueue(protocolName);
-        mPriv->introspectQueue.enqueue(&ConnectionManager::callGetParameters);
-    }
-
-    continueIntrospection();
-
     watcher->deleteLater();
 }
 
-void ConnectionManager::onGetParametersReturn(
-        QDBusPendingCallWatcher *watcher)
+void ConnectionManager::gotParameters(QDBusPendingCallWatcher *watcher)
 {
     QDBusPendingReply<ParamSpecList> reply = *watcher;
-    ParamSpecList parameters;
-    QString protocolName = mPriv->protocolQueue.dequeue();
-    ProtocolInfo *info = mPriv->protocol(protocolName);
+    QString protocolName = mPriv->parametersQueue.dequeue();
 
     if (!reply.isError()) {
-        debug() << "Got reply to ConnectionManager.GetParameters";
-        parameters = reply.value();
+        debug() << QString("Got reply to ConnectionManager.GetParameters(%1)").arg(protocolName);
+        ParamSpecList parameters = reply.value();
+        ProtocolInfo *info = mPriv->protocol(protocolName);
+        Q_FOREACH (const ParamSpec &spec, parameters) {
+            debug() << "Parameter" << spec.name << "has flags" << spec.flags
+                << "and signature" << spec.signature;
+
+            info->addParameter(spec);
+        }
     } else {
         warning().nospace() <<
-            "ConnectionManager.GetParameters failed: " <<
+            QString("ConnectionManager.GetParameters(%1) failed: ").arg(protocolName) <<
             reply.error().name() << ": " << reply.error().message();
     }
 
-    Q_FOREACH (const ParamSpec &spec, parameters) {
-        debug() << "Parameter" << spec.name << "has flags" << spec.flags
-            << "and signature" << spec.signature;
+    if (mPriv->parametersQueue.isEmpty()) {
+        // TODO should we fail if any of the protocols parameters could not be
+        //      retrieved?
+        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
 
-        info->addParameter(spec);
-    }
-
-    continueIntrospection();
-
-    watcher->deleteLater();
-}
-
-void ConnectionManager::continueIntrospection()
-{
-    if (!mPriv->ready) {
-        if (mPriv->introspectQueue.isEmpty()) {
-            debug() << "ConnectionManager is ready";
-            mPriv->ready = true;
-
-            if (mPriv->pendingReady) {
-                mPriv->pendingReady->setFinished();
-                // it will delete itself later
-                mPriv->pendingReady = 0;
+#if 0
+        Q_FOREACH (ProtocolInfo *info, mPriv->protocols) {
+            qDebug() << "protocol name   :" << info->name();
+            qDebug() << "protocol cn name:" << info->cmName();
+            Q_FOREACH (ProtocolParameter *param, info->parameters()) {
+                qDebug() << "\tparam name:       " << param->name();
+                qDebug() << "\tparam is required:" << param->isRequired();
+                qDebug() << "\tparam is secret:  " << param->isSecret();
+                qDebug() << "\tparam value:      " << param->defaultValue();
             }
-        } else {
-            (this->*(mPriv->introspectQueue.dequeue()))();
         }
+#endif
     }
+
+    watcher->deleteLater();
 }
 
 } // Telepathy::Client
diff --git a/TelepathyQt4/Client/connection-manager.h b/TelepathyQt4/Client/connection-manager.h
index 5080ab9..d26ffc4 100644
--- a/TelepathyQt4/Client/connection-manager.h
+++ b/TelepathyQt4/Client/connection-manager.h
@@ -33,13 +33,15 @@
 #include <TelepathyQt4/Client/OptionalInterfaceFactory>
 #include <TelepathyQt4/Constants>
 
+#include <QSet>
+
 namespace Telepathy
 {
 namespace Client
 {
 
 class PendingConnection;
-class PendingReadyConnectionManager;
+class PendingReady;
 class PendingStringList;
 class ProtocolParameter;
 class ProtocolInfo;
@@ -119,6 +121,7 @@ class ConnectionManager : public StatelessDBusProxy,
 
 public:
     enum Feature {
+        FeatureCore = 0,
         _Padding = 0xFFFFFFFF
     };
     Q_DECLARE_FLAGS(Features, Feature)
@@ -144,9 +147,9 @@ public:
         return OptionalInterfaceFactory<ConnectionManager>::interface<DBus::PropertiesInterface>();
     }
 
-    bool isReady(Features features = 0) const;
+    bool isReady(const QSet<uint> &features = QSet<uint>()) const;
 
-    PendingReadyConnectionManager *becomeReady(Features features = 0);
+    PendingReady *becomeReady(const QSet<uint> &requestedFeatures = QSet<uint>());
 
     static PendingStringList *listNames(const QDBusConnection &bus = QDBusConnection::sessionBus());
 
@@ -154,20 +157,13 @@ protected:
     ConnectionManagerInterface *baseInterface() const;
 
 private Q_SLOTS:
-    void onGetParametersReturn(QDBusPendingCallWatcher *);
-    void onListProtocolsReturn(QDBusPendingCallWatcher *);
-    void onGetAllConnectionManagerReturn(QDBusPendingCallWatcher *);
-    void continueIntrospection();
+    void gotMainProperties(QDBusPendingCallWatcher *);
+    void gotProtocols(QDBusPendingCallWatcher *);
+    void gotParameters(QDBusPendingCallWatcher *);
 
 private:
     Q_DISABLE_COPY(ConnectionManager);
 
-    bool checkConfigFile();
-    void callReadConfig();
-    void callGetAll();
-    void callGetParameters();
-    void callListProtocols();
-
     struct Private;
     friend struct Private;
     friend class PendingConnection;
diff --git a/tests/dbus/cm-basics.cpp b/tests/dbus/cm-basics.cpp
index cd8bf4e..6ae8289 100644
--- a/tests/dbus/cm-basics.cpp
+++ b/tests/dbus/cm-basics.cpp
@@ -6,7 +6,7 @@
 #include <QtTest/QtTest>
 
 #include <TelepathyQt4/Client/ConnectionManager>
-#include <TelepathyQt4/Client/PendingReadyConnectionManager>
+#include <TelepathyQt4/Client/PendingReady>
 #include <TelepathyQt4/Client/PendingStringList>
 #include <TelepathyQt4/Debug>
 
diff --git a/tests/pinocchio/cm-basics.cpp b/tests/pinocchio/cm-basics.cpp
index 2dabb97..12e29b7 100644
--- a/tests/pinocchio/cm-basics.cpp
+++ b/tests/pinocchio/cm-basics.cpp
@@ -5,7 +5,7 @@
 
 #include <TelepathyQt4/Client/ConnectionManager>
 #include <TelepathyQt4/Client/PendingConnection>
-#include <TelepathyQt4/Client/PendingReadyConnectionManager>
+#include <TelepathyQt4/Client/PendingReady>
 #include <TelepathyQt4/Client/PendingStringList>
 
 #include <tests/pinocchio/lib.h>
diff --git a/tests/pinocchio/conn-basics.cpp b/tests/pinocchio/conn-basics.cpp
index 9c24811..df07746 100644
--- a/tests/pinocchio/conn-basics.cpp
+++ b/tests/pinocchio/conn-basics.cpp
@@ -8,7 +8,6 @@
 #include <TelepathyQt4/Client/Connection>
 #include <TelepathyQt4/Client/ConnectionManager>
 #include <TelepathyQt4/Client/PendingReady>
-#include <TelepathyQt4/Client/PendingReadyConnectionManager>
 
 #include <tests/pinocchio/lib.h>
 
-- 
1.5.6.5




More information about the telepathy-commits mailing list