summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/dbus/qdbusconnection.cpp206
-rw-r--r--src/dbus/qdbusconnection_p.h2
-rw-r--r--src/dbus/qdbusconnectionmanager_p.h11
-rw-r--r--src/dbus/qdbusintegrator.cpp1
-rw-r--r--src/dbus/qdbusserver.cpp16
-rw-r--r--src/dbus/qdbusserver.h1
-rw-r--r--tests/auto/dbus/dbus.pro3
-rw-r--r--tests/auto/dbus/qdbusconnection/qdbusconnection.pro1
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp301
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h287
-rw-r--r--tests/auto/dbus/qdbusconnection_no_app/qdbusconnection_no_app.pro6
-rw-r--r--tests/auto/dbus/qdbusconnection_no_app/tst_qdbusconnection_no_app.cpp37
12 files changed, 520 insertions, 352 deletions
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 8ebdf4c66e..a5d674bb5a 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -59,6 +59,23 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
+struct QDBusConnectionManager::ConnectionRequestData
+{
+ enum RequestType {
+ ConnectToStandardBus,
+ ConnectToBusByAddress,
+ ConnectToPeerByAddress
+ } type;
+
+ union {
+ QDBusConnection::BusType busType;
+ const QString *busAddress;
+ };
+ const QString *name;
+
+ QDBusConnectionPrivate *result;
+};
+
QDBusConnectionPrivate *QDBusConnectionManager::connection(const QString &name) const
{
return connectionHash.value(name, 0);
@@ -80,7 +97,11 @@ void QDBusConnectionManager::removeConnection(const QString &name)
QDBusConnectionManager::QDBusConnectionManager()
{
- moveToThread(Q_NULLPTR); // we don't handle events
+ connect(this, &QDBusConnectionManager::connectionRequested,
+ this, &QDBusConnectionManager::executeConnectionRequest, Qt::BlockingQueuedConnection);
+ connect(this, &QDBusConnectionManager::serverRequested,
+ this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection);
+ moveToThread(this); // ugly, don't do this in other projects
start();
}
@@ -123,6 +144,103 @@ void QDBusConnectionManager::run()
}
}
connectionHash.clear();
+
+ // allow deletion from any thread without warning
+ moveToThread(Q_NULLPTR);
+}
+
+QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(QDBusConnection::BusType type, const QString &name)
+{
+ ConnectionRequestData data;
+ data.type = ConnectionRequestData::ConnectToStandardBus;
+ data.busType = type;
+ data.name = &name;
+
+ emit connectionRequested(&data);
+ return data.result;
+}
+
+QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(const QString &address, const QString &name)
+{
+ ConnectionRequestData data;
+ data.type = ConnectionRequestData::ConnectToBusByAddress;
+ data.busAddress = &address;
+ data.name = &name;
+
+ emit connectionRequested(&data);
+ return data.result;
+}
+
+QDBusConnectionPrivate *QDBusConnectionManager::connectToPeer(const QString &address, const QString &name)
+{
+ ConnectionRequestData data;
+ data.type = ConnectionRequestData::ConnectToPeerByAddress;
+ data.busAddress = &address;
+ data.name = &name;
+
+ emit connectionRequested(&data);
+ return data.result;
+}
+
+void QDBusConnectionManager::executeConnectionRequest(QDBusConnectionManager::ConnectionRequestData *data)
+{
+ QMutexLocker locker(&mutex);
+ const QString &name = *data->name;
+ QDBusConnectionPrivate *&d = data->result;
+
+ // check if the connection exists by name
+ d = connection(name);
+ if (d || name.isEmpty())
+ return;
+
+ d = new QDBusConnectionPrivate;
+ DBusConnection *c = 0;
+ QDBusErrorInternal error;
+ switch (data->type) {
+ case ConnectionRequestData::ConnectToStandardBus:
+ switch (data->busType) {
+ case QDBusConnection::SystemBus:
+ c = q_dbus_bus_get_private(DBUS_BUS_SYSTEM, error);
+ break;
+ case QDBusConnection::SessionBus:
+ c = q_dbus_bus_get_private(DBUS_BUS_SESSION, error);
+ break;
+ case QDBusConnection::ActivationBus:
+ c = q_dbus_bus_get_private(DBUS_BUS_STARTER, error);
+ break;
+ }
+ break;
+
+ case ConnectionRequestData::ConnectToBusByAddress:
+ case ConnectionRequestData::ConnectToPeerByAddress:
+ c = q_dbus_connection_open_private(data->busAddress->toUtf8().constData(), error);
+ if (c && data->type == ConnectionRequestData::ConnectToBusByAddress) {
+ // register on the bus
+ if (!q_dbus_bus_register(c, error)) {
+ q_dbus_connection_unref(c);
+ c = 0;
+ }
+ }
+ break;
+ }
+
+ setConnection(name, d);
+ if (data->type == ConnectionRequestData::ConnectToPeerByAddress) {
+ d->setPeer(c, error);
+ } else {
+ // create the bus service
+ // will lock in QDBusConnectionPrivate::connectRelay()
+ d->setConnection(c, error);
+ d->createBusService();
+ }
+}
+
+void QDBusConnectionManager::createServer(const QString &address, void *server)
+{
+ QDBusErrorInternal error;
+ QDBusConnectionPrivate *d = new QDBusConnectionPrivate;
+ d->setServer(static_cast<QDBusServer *>(server),
+ q_dbus_server_listen(address.toUtf8().constData(), error), error);
}
/*!
@@ -318,39 +436,7 @@ QDBusConnection QDBusConnection::connectToBus(BusType type, const QString &name)
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
-
- QMutexLocker locker(&_q_manager()->mutex);
-
- QDBusConnectionPrivate *d = _q_manager()->connection(name);
- if (d || name.isEmpty())
- return QDBusConnection(d);
-
- d = new QDBusConnectionPrivate;
- DBusConnection *c = 0;
- QDBusErrorInternal error;
- switch (type) {
- case SystemBus:
- c = q_dbus_bus_get_private(DBUS_BUS_SYSTEM, error);
- break;
- case SessionBus:
- c = q_dbus_bus_get_private(DBUS_BUS_SESSION, error);
- break;
- case ActivationBus:
- c = q_dbus_bus_get_private(DBUS_BUS_STARTER, error);
- break;
- }
- d->setConnection(c, error); //setConnection does the error handling for us
-
- _q_manager()->setConnection(name, d);
-
- QDBusConnection retval(d);
-
- // create the bus service
- // will lock in QDBusConnectionPrivate::connectRelay()
- d->setBusService(retval);
- d->moveToThread(_q_manager());
-
- return retval;
+ return QDBusConnection(_q_manager()->connectToBus(type, name));
}
/*!
@@ -364,34 +450,7 @@ QDBusConnection QDBusConnection::connectToBus(const QString &address,
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
-
- QMutexLocker locker(&_q_manager()->mutex);
-
- QDBusConnectionPrivate *d = _q_manager()->connection(name);
- if (d || name.isEmpty())
- return QDBusConnection(d);
-
- d = new QDBusConnectionPrivate;
- // setConnection does the error handling for us
- QDBusErrorInternal error;
- DBusConnection *c = q_dbus_connection_open_private(address.toUtf8().constData(), error);
- if (c) {
- if (!q_dbus_bus_register(c, error)) {
- q_dbus_connection_unref(c);
- c = 0;
- }
- }
- d->setConnection(c, error);
- _q_manager()->setConnection(name, d);
-
- QDBusConnection retval(d);
-
- // create the bus service
- // will lock in QDBusConnectionPrivate::connectRelay()
- d->setBusService(retval);
- d->moveToThread(_q_manager());
-
- return retval;
+ return QDBusConnection(_q_manager()->connectToBus(address, name));
}
/*!
\since 4.8
@@ -406,25 +465,7 @@ QDBusConnection QDBusConnection::connectToPeer(const QString &address,
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
-
- QMutexLocker locker(&_q_manager()->mutex);
-
- QDBusConnectionPrivate *d = _q_manager()->connection(name);
- if (d || name.isEmpty())
- return QDBusConnection(d);
-
- d = new QDBusConnectionPrivate;
- // setPeer does the error handling for us
- QDBusErrorInternal error;
- DBusConnection *c = q_dbus_connection_open_private(address.toUtf8().constData(), error);
-
- d->setPeer(c, error);
- _q_manager()->setConnection(name, d);
- d->moveToThread(_q_manager());
-
- QDBusConnection retval(d);
-
- return retval;
+ return QDBusConnection(_q_manager()->connectToPeer(address, name));
}
/*!
@@ -1130,9 +1171,10 @@ QDBusConnection QDBusConnection::sender()
/*!
\internal
*/
-void QDBusConnectionPrivate::setBusService(const QDBusConnection &connection)
+void QDBusConnectionPrivate::createBusService()
{
Q_ASSERT(mode == ClientMode);
+ QDBusConnection connection(this);
busService = new QDBusConnectionInterface(connection, this);
ref.deref(); // busService has increased the refcounting to us
// avoid cyclic refcounting
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index f653c427e7..765e4281fd 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -190,7 +190,7 @@ public:
explicit QDBusConnectionPrivate(QObject *parent = 0);
~QDBusConnectionPrivate();
- void setBusService(const QDBusConnection &connection);
+ void createBusService();
void setPeer(DBusConnection *connection, const QDBusErrorInternal &error);
void setConnection(DBusConnection *connection, const QDBusErrorInternal &error);
void setServer(QDBusServer *object, DBusServer *server, const QDBusErrorInternal &error);
diff --git a/src/dbus/qdbusconnectionmanager_p.h b/src/dbus/qdbusconnectionmanager_p.h
index c3c7999699..4527c562f8 100644
--- a/src/dbus/qdbusconnectionmanager_p.h
+++ b/src/dbus/qdbusconnectionmanager_p.h
@@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE
class QDBusConnectionManager : public QDaemonThread
{
Q_OBJECT
+ struct ConnectionRequestData;
public:
QDBusConnectionManager();
~QDBusConnectionManager();
@@ -65,13 +66,23 @@ public:
QDBusConnectionPrivate *connection(const QString &name) const;
void removeConnection(const QString &name);
void setConnection(const QString &name, QDBusConnectionPrivate *c);
+ QDBusConnectionPrivate *connectToBus(QDBusConnection::BusType type, const QString &name);
+ QDBusConnectionPrivate *connectToBus(const QString &address, const QString &name);
+ QDBusConnectionPrivate *connectToPeer(const QString &address, const QString &name);
mutable QMutex mutex;
+signals:
+ void connectionRequested(ConnectionRequestData *);
+ void serverRequested(const QString &address, void *server);
+
protected:
void run() Q_DECL_OVERRIDE;
private:
+ void executeConnectionRequest(ConnectionRequestData *data);
+ void createServer(const QString &address, void *server);
+
QHash<QString, QDBusConnectionPrivate *> connectionHash;
mutable QMutex senderMutex;
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index d5eaf39021..9b0a51107a 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1644,6 +1644,7 @@ void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s, const
{
mode = ServerMode;
serverObject = object;
+ object->d = this;
if (!s) {
handleError(error);
return;
diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp
index a0b2c8283c..6c1b4c10ef 100644
--- a/src/dbus/qdbusserver.cpp
+++ b/src/dbus/qdbusserver.cpp
@@ -63,14 +63,10 @@ QDBusServer::QDBusServer(const QString &address, QObject *parent)
d = 0;
return;
}
- d = new QDBusConnectionPrivate;
+ emit QDBusConnectionManager::instance()->serverRequested(address, this);
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
-
- QDBusErrorInternal error;
- d->setServer(this, q_dbus_server_listen(address.toUtf8().constData(), error), error);
- d->moveToThread(QDBusConnectionManager::instance());
}
/*!
@@ -83,23 +79,19 @@ QDBusServer::QDBusServer(QObject *parent)
{
#ifdef Q_OS_UNIX
// Use Unix sockets on Unix systems only
- static const char address[] = "unix:tmpdir=/tmp";
+ const QString address = QStringLiteral("unix:tmpdir=/tmp");
#else
- static const char address[] = "tcp:";
+ const QString address = QStringLiteral("tcp:");
#endif
if (!qdbus_loadLibDBus()) {
d = 0;
return;
}
- d = new QDBusConnectionPrivate;
+ emit QDBusConnectionManager::instance()->serverRequested(address, this);
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
-
- QDBusErrorInternal error;
- d->setServer(this, q_dbus_server_listen(address, error), error);
- d->moveToThread(QDBusConnectionManager::instance());
}
/*!
diff --git a/src/dbus/qdbusserver.h b/src/dbus/qdbusserver.h
index 2c66472a4d..3cb2ec8c50 100644
--- a/src/dbus/qdbusserver.h
+++ b/src/dbus/qdbusserver.h
@@ -69,6 +69,7 @@ private:
Q_DISABLE_COPY(QDBusServer)
Q_PRIVATE_SLOT(d, void _q_newConnection(QDBusConnectionPrivate*))
QDBusConnectionPrivate *d;
+ friend class QDBusConnectionPrivate;
};
QT_END_NAMESPACE
diff --git a/tests/auto/dbus/dbus.pro b/tests/auto/dbus/dbus.pro
index cd845d7043..bd1fef5193 100644
--- a/tests/auto/dbus/dbus.pro
+++ b/tests/auto/dbus/dbus.pro
@@ -3,6 +3,7 @@ SUBDIRS=\
qdbusabstractadaptor \
qdbusabstractinterface \
qdbusconnection \
+ qdbusconnection_no_app \
qdbusconnection_no_bus \
qdbuscontext \
qdbusinterface \
@@ -16,7 +17,7 @@ SUBDIRS=\
qdbusservicewatcher \
qdbustype \
qdbusthreading \
- qdbusxmlparser \
+ qdbusxmlparser
!contains(QT_CONFIG,private_tests): SUBDIRS -= \
qdbusmarshall \
diff --git a/tests/auto/dbus/qdbusconnection/qdbusconnection.pro b/tests/auto/dbus/qdbusconnection/qdbusconnection.pro
index 2fd62a234b..83ae29de0a 100644
--- a/tests/auto/dbus/qdbusconnection/qdbusconnection.pro
+++ b/tests/auto/dbus/qdbusconnection/qdbusconnection.pro
@@ -2,4 +2,5 @@ CONFIG += testcase
TARGET = tst_qdbusconnection
QT = core dbus testlib
SOURCES += tst_qdbusconnection.cpp
+HEADERS += tst_qdbusconnection.h
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
index 4e04e4dbab..e91f87d6c8 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
@@ -31,34 +31,15 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#include "tst_qdbusconnection.h"
+
#include <qcoreapplication.h>
#include <qdebug.h>
#include <QtTest/QtTest>
#include <QtDBus/QtDBus>
-class BaseObject: public QObject
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "local.BaseObject")
-public:
- BaseObject(QObject *parent = 0) : QObject(parent) { }
-public slots:
- void anotherMethod() { }
-};
-
-class MyObject: public BaseObject
-{
- Q_OBJECT
-public slots:
- void method(const QDBusMessage &msg);
-
-public:
- static QString path;
- int callCount;
- MyObject(QObject *parent = 0) : BaseObject(parent), callCount(0) {}
-};
-
void MyObject::method(const QDBusMessage &msg)
{
path = msg.path();
@@ -66,19 +47,6 @@ void MyObject::method(const QDBusMessage &msg)
//qDebug() << msg;
}
-class MyObjectWithoutInterface: public QObject
-{
- Q_OBJECT
-public slots:
- void method(const QDBusMessage &msg);
-
-public:
- static QString path;
- static QString interface;
- int callCount;
- MyObjectWithoutInterface(QObject *parent = 0) : QObject(parent), callCount(0) {}
-};
-
void MyObjectWithoutInterface::method(const QDBusMessage &msg)
{
path = msg.path();
@@ -87,72 +55,6 @@ void MyObjectWithoutInterface::method(const QDBusMessage &msg)
//qDebug() << msg;
}
-class tst_QDBusConnection: public QObject
-{
- Q_OBJECT
-
- int signalsReceived;
-public slots:
- void oneSlot() { ++signalsReceived; }
- void exitLoop() { ++signalsReceived; QTestEventLoop::instance().exitLoop(); }
- void secondCallWithCallback();
-
-private slots:
- void noConnection();
- void connectToBus();
- void connectToPeer();
- void connect();
- void send();
- void sendWithGui();
- void sendAsync();
- void sendSignal();
- void sendSignalToName();
- void sendSignalToOtherName();
-
- void registerObject_data();
- void registerObject();
- void registerObjectWithInterface_data();
- void registerObjectWithInterface();
- void registerObjectPeer_data();
- void registerObjectPeer();
- void registerObject2();
- void registerObjectPeer2();
-
- void registerQObjectChildren();
- void registerQObjectChildrenPeer();
-
- void callSelf();
- void callSelfByAnotherName_data();
- void callSelfByAnotherName();
- void multipleInterfacesInQObject();
-
- void slotsWithLessParameters();
- void nestedCallWithCallback();
-
- void serviceRegistrationRaceCondition();
-
- void registerVirtualObject();
- void callVirtualObject();
- void callVirtualObjectLocal();
-
-public:
- QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
- bool callMethod(const QDBusConnection &conn, const QString &path);
- bool callMethod(const QDBusConnection &conn, const QString &path, const QString &interface);
- bool callMethodPeer(const QDBusConnection &conn, const QString &path);
-};
-
-class QDBusSpy: public QObject
-{
- Q_OBJECT
-public slots:
- void handlePing(const QString &str) { args.clear(); args << str; }
- void asyncReply(const QDBusMessage &msg) { args = msg.arguments(); }
-
-public:
- QList<QVariant> args;
-};
-
void tst_QDBusConnection::noConnection()
{
QDBusConnection con = QDBusConnection::connectToBus("unix:path=/dev/null", "testconnection");
@@ -188,12 +90,13 @@ void tst_QDBusConnection::sendSignal()
msg << QLatin1String("ping");
QVERIFY(con.send(msg));
-
- QTest::qWait(1000);
}
void tst_QDBusConnection::sendSignalToName()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication"); // because of the qWait()
+
QDBusSpy spy;
QDBusConnection con = QDBusConnection::sessionBus();
@@ -216,6 +119,9 @@ void tst_QDBusConnection::sendSignalToName()
void tst_QDBusConnection::sendSignalToOtherName()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication"); // because of the qWait()
+
QDBusSpy spy;
QDBusConnection con = QDBusConnection::sessionBus();
@@ -253,6 +159,9 @@ void tst_QDBusConnection::send()
void tst_QDBusConnection::sendWithGui()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
QDBusConnection con = QDBusConnection::sessionBus();
QVERIFY(con.isConnected());
@@ -269,6 +178,9 @@ void tst_QDBusConnection::sendWithGui()
void tst_QDBusConnection::sendAsync()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
QDBusConnection con = QDBusConnection::sessionBus();
QVERIFY(con.isConnected());
@@ -290,6 +202,9 @@ void tst_QDBusConnection::connect()
QDBusConnection con = QDBusConnection::sessionBus();
+ if (!QCoreApplication::instance())
+ return; // cannot receive signals in this thread without QCoreApplication
+
con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy,
SLOT(handlePing(QString)));
@@ -483,59 +398,6 @@ void tst_QDBusConnection::registerObjectWithInterface()
QVERIFY(!callMethod(con, path, interface));
}
-class MyServer : public QDBusServer
-{
- Q_OBJECT
-public:
- MyServer(QString path) : m_path(path), m_connections()
- {
- connect(this, SIGNAL(newConnection(QDBusConnection)), SLOT(handleConnection(QDBusConnection)));
- }
-
- bool registerObject(const QDBusConnection& c)
- {
- QDBusConnection conn(c);
- if (!conn.registerObject(m_path, &m_obj, QDBusConnection::ExportAllSlots))
- return false;
- if (!(conn.objectRegisteredAt(m_path) == &m_obj))
- return false;
- return true;
- }
-
- bool registerObject()
- {
- Q_FOREACH (const QString &name, m_connections) {
- if (!registerObject(QDBusConnection(name)))
- return false;
- }
- return true;
- }
-
- void unregisterObject()
- {
- Q_FOREACH (const QString &name, m_connections) {
- QDBusConnection c(name);
- c.unregisterObject(m_path);
- }
- }
-
-public slots:
- void handleConnection(const QDBusConnection& c)
- {
- m_connections << c.name();
- QVERIFY(isConnected());
- QVERIFY(c.isConnected());
- QVERIFY(registerObject(c));
- QTestEventLoop::instance().exitLoop();
- }
-
-private:
- MyObject m_obj;
- QString m_path;
- QStringList m_connections;
-};
-
-
void tst_QDBusConnection::registerObjectPeer_data()
{
QTest::addColumn<QString>("path");
@@ -549,6 +411,9 @@ void tst_QDBusConnection::registerObjectPeer_data()
void tst_QDBusConnection::registerObjectPeer()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
QFETCH(QString, path);
MyServer server(path);
@@ -623,7 +488,6 @@ void tst_QDBusConnection::registerObject2()
MyObject obj;
QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots));
QVERIFY(callMethod(con, "/"));
- qDebug() << obj.path;
QCOMPARE(obj.path, QString("/"));
}
// make sure it's gone
@@ -635,7 +499,6 @@ void tst_QDBusConnection::registerObject2()
QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots));
QVERIFY(!callMethod(con, "/"));
QVERIFY(callMethod(con, "/p1"));
- qDebug() << obj.path;
QCOMPARE(obj.path, QString("/p1"));
// re-register it somewhere else
@@ -699,36 +562,11 @@ void tst_QDBusConnection::registerObject2()
}
}
-class MyServer2 : public QDBusServer
-{
- Q_OBJECT
-public:
- MyServer2() : m_conn("none")
- {
- connect(this, SIGNAL(newConnection(QDBusConnection)), SLOT(handleConnection(QDBusConnection)));
- }
-
- QDBusConnection connection()
- {
- return m_conn;
- }
-
-public slots:
- void handleConnection(const QDBusConnection& c)
- {
- m_conn = c;
- QVERIFY(isConnected());
- QVERIFY(m_conn.isConnected());
- QTestEventLoop::instance().exitLoop();
- }
-
-private:
- MyObject m_obj;
- QDBusConnection m_conn;
-};
-
void tst_QDBusConnection::registerObjectPeer2()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
MyServer2 server;
QDBusConnection con = QDBusConnection::connectToPeer(server.address(), "foo");
QTestEventLoop::instance().enterLoop(2);
@@ -749,7 +587,6 @@ void tst_QDBusConnection::registerObjectPeer2()
MyObject obj;
QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots));
QVERIFY(callMethodPeer(srv_con, "/"));
- qDebug() << obj.path;
QCOMPARE(obj.path, QString("/"));
}
// make sure it's gone
@@ -761,7 +598,6 @@ void tst_QDBusConnection::registerObjectPeer2()
QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots));
QVERIFY(!callMethodPeer(srv_con, "/"));
QVERIFY(callMethodPeer(srv_con, "/p1"));
- qDebug() << obj.path;
QCOMPARE(obj.path, QString("/p1"));
// re-register it somewhere else
@@ -885,6 +721,9 @@ void tst_QDBusConnection::registerQObjectChildren()
void tst_QDBusConnection::registerQObjectChildrenPeer()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
MyServer2 server;
QDBusConnection con = QDBusConnection::connectToPeer(server.address(), "foo");
QTestEventLoop::instance().enterLoop(2);
@@ -978,22 +817,6 @@ bool tst_QDBusConnection::callMethodPeer(const QDBusConnection &conn, const QStr
return (MyObject::path == path);
}
-class TestObject : public QObject
-{
-Q_OBJECT
-public:
- TestObject(QObject *parent = 0) : QObject(parent) {}
- ~TestObject() {}
-
- QString func;
-
-public slots:
- void test0() { func = "test0"; }
- void test1(int i) { func = "test1 " + QString::number(i); }
- int test2() { func = "test2"; return 43; }
- int test3(int i) { func = "test2"; return i + 1; }
-};
-
void tst_QDBusConnection::callSelf()
{
TestObject testObject;
@@ -1030,6 +853,9 @@ void tst_QDBusConnection::callSelfByAnotherName_data()
void tst_QDBusConnection::callSelfByAnotherName()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
static int counter = 0;
QString sname = serviceName() + QString::number(counter++);
@@ -1102,6 +928,9 @@ void tst_QDBusConnection::multipleInterfacesInQObject()
void tst_QDBusConnection::slotsWithLessParameters()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
QDBusConnection con = QDBusConnection::sessionBus();
QDBusMessage signal = QDBusMessage::createSignal("/", "org.qtproject.TestCase",
@@ -1128,7 +957,6 @@ void tst_QDBusConnection::slotsWithLessParameters()
void tst_QDBusConnection::secondCallWithCallback()
{
- qDebug("Hello");
QDBusConnection con = QDBusConnection::sessionBus();
QDBusMessage msg = QDBusMessage::createMethodCall(con.baseService(), "/test", QString(),
"test0");
@@ -1137,6 +965,9 @@ void tst_QDBusConnection::secondCallWithCallback()
void tst_QDBusConnection::nestedCallWithCallback()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
TestObject testObject;
QDBusConnection connection = QDBusConnection::sessionBus();
QVERIFY(connection.registerObject("/test", &testObject,
@@ -1152,22 +983,11 @@ void tst_QDBusConnection::nestedCallWithCallback()
QCOMPARE(signalsReceived, 1);
}
-class RaceConditionSignalWaiter : public QObject
-{
- Q_OBJECT
-public:
- int count;
- RaceConditionSignalWaiter() : count (0) {}
- virtual ~RaceConditionSignalWaiter() {}
-
-public slots:
- void countUp() { ++count; emit done(); }
-signals:
- void done();
-};
-
void tst_QDBusConnection::serviceRegistrationRaceCondition()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
// There was a race condition in the updating of list of name owners in
// Qt D-Bus. When the user connects to a signal coming from a given
// service, we must listen for NameOwnerChanged signals relevant to that
@@ -1219,39 +1039,6 @@ void tst_QDBusConnection::serviceRegistrationRaceCondition()
QCOMPARE(recv.count, 1);
}
-class VirtualObject: public QDBusVirtualObject
-{
- Q_OBJECT
-public:
- VirtualObject() :success(true) {}
-
- QString introspect(const QString & /* path */) const
- {
- return QString();
- }
-
- bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) {
- ++callCount;
- lastMessage = message;
-
- if (success) {
- QDBusMessage reply = message.createReply(replyArguments);
- connection.send(reply);
- }
- emit messageReceived(message);
- return success;
- }
-signals:
- void messageReceived(const QDBusMessage &message) const;
-
-public:
- mutable QDBusMessage lastMessage;
- QVariantList replyArguments;
- mutable int callCount;
- bool success;
-};
-
-
void tst_QDBusConnection::registerVirtualObject()
{
QDBusConnection con = QDBusConnection::sessionBus();
@@ -1334,6 +1121,9 @@ void tst_QDBusConnection::registerVirtualObject()
void tst_QDBusConnection::callVirtualObject()
{
+ if (!QCoreApplication::instance())
+ QSKIP("Test requires a QCoreApplication");
+
QDBusConnection con = QDBusConnection::sessionBus();
QVERIFY(con.isConnected());
@@ -1391,7 +1181,6 @@ void tst_QDBusConnection::callVirtualObject()
QVERIFY(!QTestEventLoop::instance().timeout());
QTest::qWait(100);
QVERIFY(errorReply.isError());
- qDebug() << errorReply.reply().arguments();
QCOMPARE(errorReply.reply().errorName(), QString("org.freedesktop.DBus.Error.UnknownObject"));
QDBusConnection::disconnectFromBus("con2");
@@ -1432,7 +1221,7 @@ void tst_QDBusConnection::callVirtualObjectLocal()
QString MyObject::path;
QString MyObjectWithoutInterface::path;
QString MyObjectWithoutInterface::interface;
-QTEST_MAIN(tst_QDBusConnection)
-
-#include "tst_qdbusconnection.moc"
+#ifndef tst_QDBusConnection
+QTEST_MAIN(tst_QDBusConnection)
+#endif
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
new file mode 100644
index 0000000000..a53ba320f8
--- /dev/null
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Intel Corporation.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TST_QDBUSCONNECTION_H
+#define TST_QDBUSCONNECTION_H
+
+#include <QObject>
+#include <QtDBus/QtDBus>
+#include <QtTest/QtTest>
+
+class BaseObject: public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "local.BaseObject")
+public:
+ BaseObject(QObject *parent = 0) : QObject(parent) { }
+public slots:
+ void anotherMethod() { }
+};
+
+class MyObject: public BaseObject
+{
+ Q_OBJECT
+public slots:
+ void method(const QDBusMessage &msg);
+
+public:
+ static QString path;
+ int callCount;
+ MyObject(QObject *parent = 0) : BaseObject(parent), callCount(0) {}
+};
+
+class MyObjectWithoutInterface: public QObject
+{
+ Q_OBJECT
+public slots:
+ void method(const QDBusMessage &msg);
+
+public:
+ static QString path;
+ static QString interface;
+ int callCount;
+ MyObjectWithoutInterface(QObject *parent = 0) : QObject(parent), callCount(0) {}
+};
+
+class tst_QDBusConnection: public QObject
+{
+ Q_OBJECT
+
+ int signalsReceived;
+public slots:
+ void oneSlot() { ++signalsReceived; }
+ void exitLoop() { ++signalsReceived; QTestEventLoop::instance().exitLoop(); }
+ void secondCallWithCallback();
+
+private slots:
+ void noConnection();
+ void connectToBus();
+ void connectToPeer();
+ void connect();
+ void send();
+ void sendWithGui();
+ void sendAsync();
+ void sendSignal();
+ void sendSignalToName();
+ void sendSignalToOtherName();
+
+ void registerObject_data();
+ void registerObject();
+ void registerObjectWithInterface_data();
+ void registerObjectWithInterface();
+ void registerObjectPeer_data();
+ void registerObjectPeer();
+ void registerObject2();
+ void registerObjectPeer2();
+
+ void registerQObjectChildren();
+ void registerQObjectChildrenPeer();
+
+ void callSelf();
+ void callSelfByAnotherName_data();
+ void callSelfByAnotherName();
+ void multipleInterfacesInQObject();
+
+ void slotsWithLessParameters();
+ void nestedCallWithCallback();
+
+ void serviceRegistrationRaceCondition();
+
+ void registerVirtualObject();
+ void callVirtualObject();
+ void callVirtualObjectLocal();
+
+public:
+ QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
+ bool callMethod(const QDBusConnection &conn, const QString &path);
+ bool callMethod(const QDBusConnection &conn, const QString &path, const QString &interface);
+ bool callMethodPeer(const QDBusConnection &conn, const QString &path);
+};
+
+class QDBusSpy: public QObject
+{
+ Q_OBJECT
+public slots:
+ void handlePing(const QString &str) { args.clear(); args << str; }
+ void asyncReply(const QDBusMessage &msg) { args = msg.arguments(); }
+
+public:
+ QList<QVariant> args;
+};
+
+class MyServer : public QDBusServer
+{
+ Q_OBJECT
+public:
+ MyServer(QString path) : m_path(path), m_connections()
+ {
+ connect(this, SIGNAL(newConnection(QDBusConnection)), SLOT(handleConnection(QDBusConnection)));
+ }
+
+ bool registerObject(const QDBusConnection& c)
+ {
+ QDBusConnection conn(c);
+ if (!conn.registerObject(m_path, &m_obj, QDBusConnection::ExportAllSlots))
+ return false;
+ if (!(conn.objectRegisteredAt(m_path) == &m_obj))
+ return false;
+ return true;
+ }
+
+ bool registerObject()
+ {
+ Q_FOREACH (const QString &name, m_connections) {
+ if (!registerObject(QDBusConnection(name)))
+ return false;
+ }
+ return true;
+ }
+
+ void unregisterObject()
+ {
+ Q_FOREACH (const QString &name, m_connections) {
+ QDBusConnection c(name);
+ c.unregisterObject(m_path);
+ }
+ }
+
+public slots:
+ void handleConnection(const QDBusConnection& c)
+ {
+ m_connections << c.name();
+ QVERIFY(isConnected());
+ QVERIFY(c.isConnected());
+ QVERIFY(registerObject(c));
+ QTestEventLoop::instance().exitLoop();
+ }
+
+private:
+ MyObject m_obj;
+ QString m_path;
+ QStringList m_connections;
+};
+
+class MyServer2 : public QDBusServer
+{
+ Q_OBJECT
+public:
+ MyServer2() : m_conn("none")
+ {
+ connect(this, SIGNAL(newConnection(QDBusConnection)), SLOT(handleConnection(QDBusConnection)));
+ }
+
+ QDBusConnection connection()
+ {
+ return m_conn;
+ }
+
+public slots:
+ void handleConnection(const QDBusConnection& c)
+ {
+ m_conn = c;
+ QVERIFY(isConnected());
+ QVERIFY(m_conn.isConnected());
+ QTestEventLoop::instance().exitLoop();
+ }
+
+private:
+ MyObject m_obj;
+ QDBusConnection m_conn;
+};
+
+class TestObject : public QObject
+{
+Q_OBJECT
+public:
+ TestObject(QObject *parent = 0) : QObject(parent) {}
+ ~TestObject() {}
+
+ QString func;
+
+public slots:
+ void test0() { func = "test0"; }
+ void test1(int i) { func = "test1 " + QString::number(i); }
+ int test2() { func = "test2"; return 43; }
+ int test3(int i) { func = "test2"; return i + 1; }
+};
+
+class RaceConditionSignalWaiter : public QObject
+{
+ Q_OBJECT
+public:
+ int count;
+ RaceConditionSignalWaiter() : count (0) {}
+ virtual ~RaceConditionSignalWaiter() {}
+
+public slots:
+ void countUp() { ++count; emit done(); }
+signals:
+ void done();
+};
+
+class VirtualObject: public QDBusVirtualObject
+{
+ Q_OBJECT
+public:
+ VirtualObject() :success(true) {}
+
+ QString introspect(const QString & /* path */) const
+ {
+ return QString();
+ }
+
+ bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) {
+ ++callCount;
+ lastMessage = message;
+
+ if (success) {
+ QDBusMessage reply = message.createReply(replyArguments);
+ connection.send(reply);
+ }
+ emit messageReceived(message);
+ return success;
+ }
+signals:
+ void messageReceived(const QDBusMessage &message) const;
+
+public:
+ mutable QDBusMessage lastMessage;
+ QVariantList replyArguments;
+ mutable int callCount;
+ bool success;
+};
+
+
+#endif // TST_QDBUSCONNECTION_H
+
diff --git a/tests/auto/dbus/qdbusconnection_no_app/qdbusconnection_no_app.pro b/tests/auto/dbus/qdbusconnection_no_app/qdbusconnection_no_app.pro
new file mode 100644
index 0000000000..ba3a13caa9
--- /dev/null
+++ b/tests/auto/dbus/qdbusconnection_no_app/qdbusconnection_no_app.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+TARGET = tst_qdbusconnection_no_app
+QT = core dbus testlib
+SOURCES += tst_qdbusconnection_no_app.cpp
+HEADERS += ../qdbusconnection/tst_qdbusconnection.h
+DEFINES += SRCDIR=\\\"$$PWD/\\\" tst_QDBusConnection=tst_QDBusConnection_NoApplication
diff --git a/tests/auto/dbus/qdbusconnection_no_app/tst_qdbusconnection_no_app.cpp b/tests/auto/dbus/qdbusconnection_no_app/tst_qdbusconnection_no_app.cpp
new file mode 100644
index 0000000000..816f75f82e
--- /dev/null
+++ b/tests/auto/dbus/qdbusconnection_no_app/tst_qdbusconnection_no_app.cpp
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Ugly hack, look away
+#include "../qdbusconnection/tst_qdbusconnection.cpp"
+
+QTEST_APPLESS_MAIN(tst_QDBusConnection_NoApplication)