diff options
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 3 | ||||
-rw-r--r-- | src/dbus/qdbusmessage.cpp | 30 | ||||
-rw-r--r-- | src/dbus/qdbusmessage.h | 2 | ||||
-rw-r--r-- | tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp | 45 |
4 files changed, 78 insertions, 2 deletions
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index a95d96e526..6a2a657714 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1904,7 +1904,8 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message) qPrintable(message.interface()), qPrintable(message.member()), qPrintable(error.message())); else if (message.type() == QDBusMessage::SignalMessage) - qWarning("QDBusConnection: error: could not send signal path \"%s\" interface \"%s\" member \"%s\": %s", + qWarning("QDBusConnection: error: could not send signal to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", + qPrintable(message.service()), qPrintable(message.path()), qPrintable(message.interface()), qPrintable(message.member()), qPrintable(error.message())); diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index 491e1273e7..76e994bbcf 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -153,8 +153,10 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB } break; case QDBusMessage::SignalMessage: - // nothing can be empty here + // only the service name can be empty here if (!d_ptr->parametersValidated) { + if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) + return 0; if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) return 0; if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) @@ -165,6 +167,7 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(), d_ptr->name.toUtf8()); + q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8())); break; } @@ -372,6 +375,31 @@ QDBusMessage QDBusMessage::createSignal(const QString &path, const QString &inte } /*! + \since 5.6 + + Constructs a new DBus message with the given \a path, \a interface + and \a name, representing a signal emission to \a destination. + + A DBus signal is emitted from one application and is received only by + the application owning the destination service name. + + The QDBusMessage object that is returned can be sent using the + QDBusConnection::send() function. +*/ +QDBusMessage QDBusMessage::createTargetedSignal(const QString &service, const QString &path, + const QString &interface, const QString &name) +{ + QDBusMessage message; + message.d_ptr->type = SignalMessage; + message.d_ptr->service = service; + message.d_ptr->path = path; + message.d_ptr->interface = interface; + message.d_ptr->name = name; + + return message; +} + +/*! Constructs a new DBus message representing a method call. A method call always informs its destination address (\a service, \a path, \a interface and \a method). diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h index 77f34ec5e2..640226e77a 100644 --- a/src/dbus/qdbusmessage.h +++ b/src/dbus/qdbusmessage.h @@ -67,6 +67,8 @@ public: static QDBusMessage createSignal(const QString &path, const QString &interface, const QString &name); + static QDBusMessage createTargetedSignal(const QString &service, const QString &path, + const QString &interface, const QString &name); static QDBusMessage createMethodCall(const QString &destination, const QString &path, const QString &interface, const QString &method); static QDBusMessage createError(const QString &name, const QString &msg); diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp index 32c228c186..d85e842a23 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp @@ -105,6 +105,8 @@ private slots: void sendWithGui(); void sendAsync(); void sendSignal(); + void sendSignalToName(); + void sendSignalToOtherName(); void registerObject_data(); void registerObject(); @@ -189,6 +191,49 @@ void tst_QDBusConnection::sendSignal() QTest::qWait(1000); } +void tst_QDBusConnection::sendSignalToName() +{ + QDBusSpy spy; + + QDBusConnection con = QDBusConnection::sessionBus(); + + con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy, + SLOT(handlePing(QString))); + + QDBusMessage msg = + QDBusMessage::createTargetedSignal(con.baseService(), "/org/kde/selftest", + "org.kde.selftest", "ping"); + msg << QLatin1String("ping"); + + QVERIFY(con.send(msg)); + + QTest::qWait(1000); + + QCOMPARE(spy.args.count(), 1); + QCOMPARE(spy.args.at(0).toString(), QString("ping")); +} + +void tst_QDBusConnection::sendSignalToOtherName() +{ + QDBusSpy spy; + + QDBusConnection con = QDBusConnection::sessionBus(); + + con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy, + SLOT(handlePing(QString))); + + QDBusMessage msg = + QDBusMessage::createTargetedSignal("some.other.service", "/org/kde/selftest", + "org.kde.selftest", "ping"); + msg << QLatin1String("ping"); + + QVERIFY(con.send(msg)); + + QTest::qWait(1000); + + QCOMPARE(spy.args.count(), 0); +} + void tst_QDBusConnection::send() { QDBusConnection con = QDBusConnection::sessionBus(); |