Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qdbusconnection.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qdbusconnection.h"
6#include "qdbusconnection_p.h"
7
8#include <qdebug.h>
9#include <qstringlist.h>
10
12#include "qdbuserror.h"
13#include "qdbusmessage.h"
14#include "qdbusutil_p.h"
16#include "qdbuspendingcall_p.h"
17#include "qdbusthreaddebug_p.h"
18
19#include <algorithm>
20
21#ifdef interface
22#undef interface
23#endif
24
25#ifndef QT_NO_DBUS
26
28
152{
153 if (name.isEmpty()) {
154 d = nullptr;
155 return;
156 }
157
159
160 if (!manager) {
161 d = nullptr;
162 } else {
163 d = manager->existingConnection(name);
164 }
165}
166
171{
172 d = other.d;
173 if (d)
174 d->ref.ref();
175}
176
182{
183 d = dd;
184 if (d)
185 d->ref.ref();
186}
187
193{
194 if (d && !d->ref.deref())
195 d->deleteLater();
196}
197
206{
207 if (other.d)
208 other.d->ref.ref();
209 if (d && !d->ref.deref())
210 d->deleteLater();
211 d = other.d;
212 return *this;
213}
214
221{
223
224 if (!manager || !qdbus_loadLibDBus()) {
225 QDBusConnectionPrivate *d = nullptr;
226 return QDBusConnection(d);
227 }
228 return QDBusConnection(manager->connectToBus(type, name, false));
229}
230
236 const QString &name)
237{
239
240 if (!manager || !qdbus_loadLibDBus()) {
241 QDBusConnectionPrivate *d = nullptr;
242 return QDBusConnection(d);
243 }
244 return QDBusConnection(manager->connectToBus(address, name));
245}
253 const QString &name)
254{
256
257 if (!manager || !qdbus_loadLibDBus()) {
258 QDBusConnectionPrivate *d = nullptr;
259 return QDBusConnection(d);
260 }
261 return QDBusConnection(manager->connectToPeer(address, name));
262}
263
273{
275 if (!manager)
276 return;
277
279}
280
292{
294 if (!manager)
295 return;
296
298}
299
308{
309 if (!d || !d->connection) {
312 if (d)
313 d->lastError = err;
314 return false;
315 }
316 return d->send(message);
317}
318
339 const char *returnMethod, const char *errorMethod,
340 int timeout) const
341{
342 if (!d || !d->connection) {
345 if (d)
346 d->lastError = err;
347 return false;
348 }
349 return d->sendWithReplyAsync(message, receiver, returnMethod, errorMethod, timeout) != nullptr;
350}
351
370 const char *returnMethod, int timeout) const
371{
372 return callWithCallback(message, receiver, returnMethod, nullptr, timeout);
373}
374
399{
400 if (!d || !d->connection) {
403 if (d)
404 d->lastError = err;
405
406 return QDBusMessage::createError(err);
407 }
408
409 if (mode != QDBus::NoBlock)
410 return d->sendWithReply(message, mode, timeout);
411
412 d->send(message);
413 QDBusMessage retval;
414 retval << QVariant(); // add one argument (to avoid .at(0) problems)
415 return retval;
416}
417
439{
440 if (!d || !d->connection) {
441 return QDBusPendingCall(nullptr); // null pointer -> disconnected
442 }
443
444 QDBusPendingCallPrivate *priv = d->sendWithReplyAsync(message, nullptr, nullptr, nullptr, timeout);
445 return QDBusPendingCall(priv);
446}
447
459bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
460 const QString &name, QObject *receiver, const char *slot)
461{
462 return connect(service, path, interface, name, QStringList(), QString(), receiver, slot);
463}
464
482bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
483 const QString &name, const QString &signature,
484 QObject *receiver, const char *slot)
485{
486 return connect(service, path, interface, name, QStringList(), signature, receiver, slot);
487}
488
512bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
513 const QString &name, const QStringList &argumentMatch, const QString &signature,
514 QObject *receiver, const char *slot)
515{
516
517 if (!receiver || !slot || !d || !d->connection)
518 return false;
519 if (interface.isEmpty() && name.isEmpty())
520 return false;
522#ifndef QT_NO_DEBUG
523 qWarning("QDBusConnection::connect: interface name '%s' is not valid", interface.toLatin1().constData());
524#endif
525 return false;
526 }
527 if (!service.isEmpty() && !QDBusUtil::isValidBusName(service)) {
528#ifndef QT_NO_DEBUG
529 qWarning("QDBusConnection::connect: service name '%s' is not valid", service.toLatin1().constData());
530#endif
531 return false;
532 }
533 if (!path.isEmpty() && !QDBusUtil::isValidObjectPath(path)) {
534#ifndef QT_NO_DEBUG
535 qWarning("QDBusConnection::connect: object path '%s' is not valid", path.toLatin1().constData());
536#endif
537 return false;
538 }
539
540 return d->connectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot);
541}
542
551 const QString &name, QObject *receiver, const char *slot)
552{
553 return disconnect(service, path, interface, name, QStringList(), QString(), receiver, slot);
554}
555
567 const QString &name, const QString &signature,
568 QObject *receiver, const char *slot)
569{
570 return disconnect(service, path, interface, name, QStringList(), signature, receiver, slot);
571}
572
585 const QString &name, const QStringList &argumentMatch, const QString &signature,
586 QObject *receiver, const char *slot)
587{
588 if (!receiver || !slot || !d || !d->connection)
589 return false;
591 return false;
592 if (interface.isEmpty() && name.isEmpty())
593 return false;
594
595 return d->disconnectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot);
596}
597
614bool QDBusConnection::registerObject(const QString &path, QObject *object, RegisterOptions options)
615{
616 return registerObject(path, QString(), object, options);
617}
618
638bool QDBusConnection::registerObject(const QString &path, const QString &interface, QObject *object, RegisterOptions options)
639{
640 Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), "QDBusConnection::registerObject",
641 "Invalid object path given");
642 if (!d || !d->connection || !object || !options || !QDBusUtil::isValidObjectPath(path))
643 return false;
644
645 auto pathComponents = QStringView{path}.split(u'/');
646 if (pathComponents.constLast().isEmpty())
647 pathComponents.removeLast();
649
650 // lower-bound search for where this object should enter in the tree
652 int i = 1;
653 while (node) {
654 if (pathComponents.size() == i) {
655 // this node exists
656 // consider it free if there's no object here and the user is not trying to
657 // replace the object sub-tree
658 if (node->obj)
659 return false;
660
662 if (options & SubPath && !node->children.isEmpty())
663 return false;
664 } else {
665 if ((options & ExportChildObjects && !node->children.isEmpty()))
666 return false;
667 }
668 // we can add the object here
669 node->obj = object;
670 node->flags = options;
671 node->interfaceName = interface;
672
673 d->registerObject(node);
674 //qDebug("REGISTERED FOR %s", path.toLocal8Bit().constData());
675 return true;
676 }
677
678 // if a virtual object occupies this path, return false
680 //qDebug("Cannot register object at %s because QDBusVirtualObject handles all sub-paths.",
681 // qPrintable(path));
682 return false;
683 }
684
685 // find the position where we'd insert the node
687 std::lower_bound(node->children.begin(), node->children.end(), pathComponents.at(i));
688 if (it != node->children.end() && it->name == pathComponents.at(i)) {
689 // match: this node exists
690 node = &(*it);
691
692 // are we allowed to go deeper?
693 if (node->flags & ExportChildObjects) {
694 // we're not
695 //qDebug("Cannot register object at %s because %s exports its own child objects",
696 // qPrintable(path), qPrintable(pathComponents.at(i)));
697 return false;
698 }
699 } else {
700 // add entry
701 it = node->children.insert(it, pathComponents.at(i).toString());
702 node = &(*it);
703 }
704
705 // iterate
706 ++i;
707 }
708
709 Q_ASSERT_X(false, "QDBusConnection::registerObject", "The impossible happened");
710 return false;
711}
712
723{
724 int opts = options | QDBusConnectionPrivate::VirtualObject;
725 return registerObject(path, (QObject*) treeNode, (RegisterOptions) opts);
726}
727
742
748{
749 Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), "QDBusConnection::registeredObject",
750 "Invalid object path given");
752 return nullptr;
753
754 auto pathComponents = QStringView{path}.split(u'/');
755 if (pathComponents.constLast().isEmpty())
756 pathComponents.removeLast();
757
758 // lower-bound search for where this object should enter in the tree
761
762 int i = 1;
763 while (node) {
764 if (pathComponents.size() == i)
765 return node->obj;
767 return node->obj;
768
770 std::lower_bound(node->children.constBegin(), node->children.constEnd(), pathComponents.at(i));
771 if (it == node->children.constEnd() || it->name != pathComponents.at(i))
772 break; // node not found
773
774 node = &(*it);
775 ++i;
776 }
777 return nullptr;
778}
779
780
781
787{
789 return nullptr;
790 return d->busService;
791}
792
804{
805 return d ? d->connection : nullptr;
806}
807
812{
813 return d && d->connection && q_dbus_connection_get_is_connected(d->connection);
814}
815
829
841{
842 return d ? d->baseService : QString();
843}
844
863{
864 return d ? d->name : QString();
865}
866
874QDBusConnection::ConnectionCapabilities QDBusConnection::connectionCapabilities() const
875{
876 return d ? d->connectionCapabilities() : ConnectionCapabilities();
877}
878
887{
888 if (interface() && interface()->registerService(serviceName)) {
889 if (d) d->registerService(serviceName);
890 return true;
891 }
892 return false;
893}
894
903{
904 if (interface()->unregisterService(serviceName)) {
905 if (d) d->unregisterService(serviceName);
906 return true;
907 }
908 return false;
909}
910
919{
921
922 if (!manager)
923 return QDBusConnection(nullptr);
924 return QDBusConnection(manager->busConnection(SessionBus));
925}
926
935{
937
938 if (!manager)
939 return QDBusConnection(nullptr);
940 return QDBusConnection(manager->busConnection(SystemBus));
941}
942
947{
951 ref.deref(); // busService has increased the refcounting to us
952 // avoid cyclic refcounting
953
957}
958
973{
974 char *dbus_machine_id = q_dbus_get_local_machine_id();
975 QByteArray result = dbus_machine_id;
976 q_dbus_free(dbus_machine_id);
977 return result;
978}
979
1014
1015#include "moc_qdbusconnection_p.cpp"
1016#include "moc_qdbusconnection.cpp"
1017
1018#endif // QT_NO_DBUS
bool ref() noexcept
bool deref() noexcept
\inmodule QtCore
Definition qbytearray.h:57
void callWithCallbackFailed(const QDBusError &error, const QDBusMessage &call)
This signal is emitted when there is an error during a QDBusConnection::callWithCallback().
static QDBusConnectionManager * instance()
void unregisterService(const QString &serviceName)
void registerObject(const ObjectTreeNode *node)
QDBusPendingCallPrivate * sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, const char *returnMethod, const char *errorMethod, int timeout=-1)
bool connectSignal(const QString &service, const QString &path, const QString &interface, const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot)
QDBusMessage sendWithReply(const QDBusMessage &message, QDBus::CallMode mode, int timeout=-1)
void unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode)
QDBusConnection::ConnectionCapabilities connectionCapabilities() const
bool send(const QDBusMessage &message)
QDBusConnectionInterface * busService
bool disconnectSignal(const QString &service, const QString &path, const QString &interface, const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot)
void registerService(const QString &serviceName)
DBusConnection * connection
void callWithCallbackFailed(const QDBusError &error, const QDBusMessage &message)
\inmodule QtDBus
bool send(const QDBusMessage &message) const
Sends the message over this connection, without waiting for a reply.
static QDBusConnection systemBus()
Returns a QDBusConnection object opened with the system bus.
bool disconnect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
Disconnects the signal specified by the service, path, interface and name parameters from the slot sl...
void * internalPointer() const
bool registerVirtualObject(const QString &path, QDBusVirtualObject *object, VirtualObjectRegisterOption options=SingleNode)
static QByteArray localMachineId()
static QDBusConnection connectToPeer(const QString &address, const QString &name)
QDBusConnection(const QString &name)
Creates a QDBusConnection object attached to the connection with name name.
bool callWithCallback(const QDBusMessage &message, QObject *receiver, const char *returnMethod, const char *errorMethod, int timeout=-1) const
Sends the message over this connection and returns immediately.
BusType
Specifies the type of the bus connection.
QDBusConnectionInterface * interface() const
Returns a QDBusConnectionInterface object that represents the D-Bus server interface on this connecti...
bool unregisterService(const QString &serviceName)
Unregisters the service serviceName that was previously registered with registerService() and returns...
bool isConnected() const
Returns true if this QDBusConnection object is connected.
static QDBusConnection connectToBus(BusType type, const QString &name)
Opens a connection of type type to one of the known buses and associate with it the connection name n...
ConnectionCapabilities connectionCapabilities() const
QDBusMessage call(const QDBusMessage &message, QDBus::CallMode mode=QDBus::Block, int timeout=-1) const
Sends the message over this connection and blocks, waiting for a reply, for at most timeout milliseco...
QString name() const
bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
Connects the signal specified by the service, path, interface and name parameters to the slot slot in...
static QDBusConnection sessionBus()
Returns a QDBusConnection object opened with the session bus.
static void disconnectFromPeer(const QString &name)
static void disconnectFromBus(const QString &name)
Closes the bus connection of name name.
~QDBusConnection()
Disposes of this object.
UnregisterMode
The mode for unregistering an object path:
bool registerService(const QString &serviceName)
Attempts to register the serviceName on the D-Bus server and returns true if the registration succeed...
QObject * objectRegisteredAt(const QString &path) const
Return the object that was registered with the registerObject() at the object path given by path.
void unregisterObject(const QString &path, UnregisterMode mode=UnregisterNode)
Unregisters an object that was registered with the registerObject() at the object path given by path ...
QString baseService() const
Returns the unique connection name for this connection, if this QDBusConnection object is connected,...
QDBusPendingCall asyncCall(const QDBusMessage &message, int timeout=-1) const
bool registerObject(const QString &path, QObject *object, RegisterOptions options=ExportAdaptors)
Registers the object object at path path and returns true if the registration was successful.
QDBusError lastError() const
Returns the last error that happened in this connection.
QDBusConnection & operator=(QDBusConnection &&other) noexcept
\inmodule QtDBus
Definition qdbuserror.h:21
\inmodule QtDBus
static QDBusMessage createError(const QString &name, const QString &msg)
Constructs a new DBus message representing an error, with the given name and msg.
\inmodule QtDBus
bool isEmpty() const noexcept
Definition qlist.h:401
iterator insert(qsizetype i, parameter_type t)
Definition qlist.h:488
iterator end()
Definition qlist.h:626
const_iterator constBegin() const noexcept
Definition qlist.h:632
iterator begin()
Definition qlist.h:625
const_iterator constEnd() const noexcept
Definition qlist.h:633
const_iterator ConstIterator
Definition qlist.h:250
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
Q_CORE_EXPORT QList< QStringView > split(QStringView sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the view into substring views wherever sep occurs, and returns the list of those string views.
Definition qstring.cpp:8249
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qvariant.h:65
QSet< QString >::iterator it
bool isValidInterfaceName(const QString &ifaceName)
Returns true if this is ifaceName is a valid interface name.
bool isValidBusName(const QString &busName)
Returns true if busName is a valid bus name.
bool isValidObjectPath(const QString &path)
Returns true if path is valid object path.
QString disconnectedErrorMessage()
CallMode
This enum describes the various ways of placing a function call.
Combined button and popup list for selecting options.
@ QueuedConnection
QList< QString > QStringList
Constructs a string list that contains the given string, str.
bool qdbus_loadLibDBus()
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char * interface
@ ObjectRegisteredAtAction
@ UnregisterObjectAction
@ RegisterObjectAction
#define qWarning
Definition qlogging.h:166
static const QMetaObjectPrivate * priv(const uint *data)
GLenum mode
GLuint object
[3]
GLbitfield GLuint64 timeout
[4]
GLenum type
GLuint GLsizei const GLchar * message
GLint ref
GLuint name
GLuint GLuint64EXT address
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
#define emit
myObject disconnect()
[26]
QReadWriteLock lock
[0]
QSharedPointer< T > other(t)
[5]
QNetworkAccessManager manager
QDBusConnection::RegisterOptions flags