1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtDBus module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qdbusconnection.h"
42#include "qdbusconnection_p.h"
43
44#include <qdebug.h>
45#include <qcoreapplication.h>
46#include <qstringlist.h>
47#include <qtimer.h>
48#include <qthread.h>
49#include <QtCore/private/qlocking_p.h>
50
51#include "qdbusconnectioninterface.h"
52#include "qdbuserror.h"
53#include "qdbusmessage.h"
54#include "qdbusmessage_p.h"
55#include "qdbusinterface_p.h"
56#include "qdbusutil_p.h"
57#include "qdbusconnectionmanager_p.h"
58#include "qdbuspendingcall_p.h"
59
60#include "qdbusthreaddebug_p.h"
61
62#include <algorithm>
63
64#ifdef interface
65#undef interface
66#endif
67
68#ifndef QT_NO_DBUS
69
70QT_BEGIN_NAMESPACE
71
72#ifdef Q_OS_WIN
73static void preventDllUnload();
74#endif
75
76Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
77
78QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::BusType type)
79{
80 static_assert(int(QDBusConnection::SessionBus) + int(QDBusConnection::SystemBus) == 1);
81 Q_ASSERT(type == QDBusConnection::SessionBus || type == QDBusConnection::SystemBus);
82
83 if (!qdbus_loadLibDBus())
84 return nullptr;
85
86 // we'll start in suspended delivery mode if we're in the main thread
87 // (the event loop will resume delivery)
88 bool suspendedDelivery = qApp && qApp->thread() == QThread::currentThread();
89
90 const auto locker = qt_scoped_lock(defaultBusMutex);
91 if (defaultBuses[type])
92 return defaultBuses[type];
93
94 QString name = QStringLiteral("qt_default_session_bus");
95 if (type == QDBusConnection::SystemBus)
96 name = QStringLiteral("qt_default_system_bus");
97 return defaultBuses[type] = connectToBus(type, name, suspendedDelivery);
98}
99
100QDBusConnectionPrivate *QDBusConnectionManager::connection(const QString &name) const
101{
102 return connectionHash.value(name, nullptr);
103}
104
105void QDBusConnectionManager::removeConnection(const QString &name)
106{
107 QDBusConnectionPrivate *d = nullptr;
108 d = connectionHash.take(name);
109 if (d && !d->ref.deref())
110 d->deleteLater();
111
112 // Static objects may be keeping the connection open.
113 // However, it is harmless to have outstanding references to a connection that is
114 // closing as long as those references will be soon dropped without being used.
115
116 // ### Output a warning if connections are being used after they have been removed.
117}
118
119QDBusConnectionManager::QDBusConnectionManager()
120{
121 connect(this, &QDBusConnectionManager::connectionRequested,
122 this, &QDBusConnectionManager::executeConnectionRequest, Qt::BlockingQueuedConnection);
123 connect(this, &QDBusConnectionManager::serverRequested,
124 this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection);
125 moveToThread(this); // ugly, don't do this in other projects
126
127#ifdef Q_OS_WIN
128 // prevent the library from being unloaded on Windows. See comments in the function.
129 preventDllUnload();
130#endif
131 defaultBuses[0] = defaultBuses[1] = nullptr;
132 start();
133}
134
135QDBusConnectionManager::~QDBusConnectionManager()
136{
137 quit();
138 wait();
139}
140
141QDBusConnectionManager* QDBusConnectionManager::instance()
142{
143 return _q_manager();
144}
145
146Q_DBUS_EXPORT void qDBusBindToApplication();
147void qDBusBindToApplication()
148{
149}
150
151void QDBusConnectionManager::setConnection(const QString &name, QDBusConnectionPrivate *c)
152{
153 connectionHash[name] = c;
154 c->name = name;
155}
156
157void QDBusConnectionManager::run()
158{
159 exec();
160
161 // cleanup:
162 const auto locker = qt_scoped_lock(mutex);
163 for (QHash<QString, QDBusConnectionPrivate *>::const_iterator it = connectionHash.constBegin();
164 it != connectionHash.constEnd(); ++it) {
165 QDBusConnectionPrivate *d = it.value();
166 if (!d->ref.deref()) {
167 delete d;
168 } else {
169 d->closeConnection();
170 d->moveToThread(nullptr); // allow it to be deleted in another thread
171 }
172 }
173 connectionHash.clear();
174
175 // allow deletion from any thread without warning
176 moveToThread(nullptr);
177}
178
179QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(QDBusConnection::BusType type, const QString &name,
180 bool suspendedDelivery)
181{
182 ConnectionRequestData data;
183 data.type = ConnectionRequestData::ConnectToStandardBus;
184 data.busType = type;
185 data.name = &name;
186 data.suspendedDelivery = suspendedDelivery;
187
188 emit connectionRequested(&data);
189 if (suspendedDelivery && data.result->connection) {
190 data.result->ref.ref();
191 QDBusConnectionDispatchEnabler *o = new QDBusConnectionDispatchEnabler(data.result);
192 QTimer::singleShot(0, o, SLOT(execute()));
193 o->moveToThread(qApp->thread()); // qApp was checked in the caller
194 }
195 return data.result;
196}
197
198QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(const QString &address, const QString &name)
199{
200 ConnectionRequestData data;
201 data.type = ConnectionRequestData::ConnectToBusByAddress;
202 data.busAddress = &address;
203 data.name = &name;
204 data.suspendedDelivery = false;
205
206 emit connectionRequested(&data);
207 return data.result;
208}
209
210QDBusConnectionPrivate *QDBusConnectionManager::connectToPeer(const QString &address, const QString &name)
211{
212 ConnectionRequestData data;
213 data.type = ConnectionRequestData::ConnectToPeerByAddress;
214 data.busAddress = &address;
215 data.name = &name;
216 data.suspendedDelivery = false;
217
218 emit connectionRequested(&data);
219 return data.result;
220}
221
222void QDBusConnectionManager::executeConnectionRequest(QDBusConnectionManager::ConnectionRequestData *data)
223{
224 const auto locker = qt_scoped_lock(mutex);
225 const QString &name = *data->name;
226 QDBusConnectionPrivate *&d = data->result;
227
228 // check if the connection exists by name
229 d = connection(name);
230 if (d || name.isEmpty())
231 return;
232
233 d = new QDBusConnectionPrivate;
234 DBusConnection *c = nullptr;
235 QDBusErrorInternal error;
236 switch (data->type) {
237 case ConnectionRequestData::ConnectToStandardBus:
238 switch (data->busType) {
239 case QDBusConnection::SystemBus:
240 c = q_dbus_bus_get_private(DBUS_BUS_SYSTEM, error);
241 break;
242 case QDBusConnection::SessionBus:
243 c = q_dbus_bus_get_private(DBUS_BUS_SESSION, error);
244 break;
245 case QDBusConnection::ActivationBus:
246 c = q_dbus_bus_get_private(DBUS_BUS_STARTER, error);
247 break;
248 }
249 break;
250
251 case ConnectionRequestData::ConnectToBusByAddress:
252 case ConnectionRequestData::ConnectToPeerByAddress:
253 c = q_dbus_connection_open_private(data->busAddress->toUtf8().constData(), error);
254 if (c && data->type == ConnectionRequestData::ConnectToBusByAddress) {
255 // register on the bus
256 if (!q_dbus_bus_register(c, error)) {
257 q_dbus_connection_unref(c);
258 c = nullptr;
259 }
260 }
261 break;
262 }
263
264 setConnection(name, d);
265 if (data->type == ConnectionRequestData::ConnectToPeerByAddress) {
266 d->setPeer(c, error);
267 } else {
268 // create the bus service
269 // will lock in QDBusConnectionPrivate::connectRelay()
270 d->setConnection(c, error);
271 d->createBusService();
272 if (c && data->suspendedDelivery)
273 d->setDispatchEnabled(false);
274 }
275}
276
277void QDBusConnectionManager::createServer(const QString &address, void *server)
278{
279 QDBusErrorInternal error;
280 QDBusConnectionPrivate *d = new QDBusConnectionPrivate;
281 d->setServer(static_cast<QDBusServer *>(server),
282 q_dbus_server_listen(address.toUtf8().constData(), error), error);
283}
284
285/*!
286 \class QDBusConnection
287 \inmodule QtDBus
288 \since 4.2
289
290 \brief The QDBusConnection class represents a connection to the D-Bus bus daemon.
291
292 This class is the initial point in a D-Bus session. Using it, you
293 can get access to remote objects, interfaces; connect remote
294 signals to your object's slots; register objects, etc.
295
296 D-Bus connections are created using the connectToBus() function,
297 which opens a connection to the server daemon and does the initial
298 handshaking, associating that connection with a name. Further
299 attempts to connect using the same name will return the same
300 connection.
301
302 The connection is then torn down using the disconnectFromBus()
303 function.
304
305 Once disconnected, calling connectToBus() will not reestablish a
306 connection, you must create a new QDBusConnection instance.
307
308 As a convenience for the two most common connection types, the
309 sessionBus() and systemBus() functions return open connections to
310 the session server daemon and the system server daemon,
311 respectively. Those connections are opened when first used and are
312 closed when the QCoreApplication destructor is run.
313
314 D-Bus also supports peer-to-peer connections, without the need for
315 a bus server daemon. Using this facility, two applications can
316 talk to each other and exchange messages. This can be achieved by
317 passing an address to connectToBus() function, which was opened by
318 another D-Bus application using QDBusServer.
319*/
320
321/*!
322 \enum QDBusConnection::BusType
323 Specifies the type of the bus connection. The valid bus types are:
324
325 \value SessionBus the session bus, associated with the running desktop session
326 \value SystemBus the system bus, used to communicate with system-wide processes
327 \value ActivationBus the activation bus, the "alias" for the bus that started the
328 service
329
330 On the Session Bus, one can find other applications by the same user that are sharing the same
331 desktop session (hence the name). On the System Bus, however, processes shared for the whole
332 system are usually found.
333*/
334
335/*!
336 \enum QDBusConnection::RegisterOption
337 Specifies the options for registering objects with the connection. The possible values are:
338
339 \value ExportAdaptors export the contents of adaptors found in this object
340
341 \value ExportScriptableSlots export this object's scriptable slots
342 \value ExportScriptableSignals export this object's scriptable signals
343 \value ExportScriptableProperties export this object's scriptable properties
344 \value ExportScriptableInvokables export this object's scriptable invokables
345 \value ExportScriptableContents shorthand form for ExportScriptableSlots |
346 ExportScriptableSignals |
347 ExportScriptableProperties
348
349 \value ExportNonScriptableSlots export this object's non-scriptable slots
350 \value ExportNonScriptableSignals export this object's non-scriptable signals
351 \value ExportNonScriptableProperties export this object's non-scriptable properties
352 \value ExportNonScriptableInvokables export this object's non-scriptable invokables
353 \value ExportNonScriptableContents shorthand form for ExportNonScriptableSlots |
354 ExportNonScriptableSignals |
355 ExportNonScriptableProperties
356
357 \value ExportAllSlots export all of this object's slots
358 \value ExportAllSignals export all of this object's signals
359 \value ExportAllProperties export all of this object's properties
360 \value ExportAllInvokables export all of this object's invokables
361 \value ExportAllContents export all of this object's contents
362 \value ExportChildObjects export this object's child objects
363
364 \sa registerObject(), QDBusAbstractAdaptor, {usingadaptors.html}{Using adaptors}
365*/
366
367/*!
368 \internal
369 \since 4.8
370 \enum QDBusConnection::VirtualObjectRegisterOption
371 Specifies the options for registering virtual objects with the connection. The possible values are:
372
373 \value SingleNode register a virtual object to handle one path only
374 \value SubPath register a virtual object so that it handles all sub paths
375
376 \sa registerVirtualObject(), QDBusVirtualObject
377*/
378
379/*!
380 \enum QDBusConnection::UnregisterMode
381 The mode for unregistering an object path:
382
383 \value UnregisterNode unregister this node only: do not unregister child objects
384 \value UnregisterTree unregister this node and all its sub-tree
385
386 Note, however, if this object was registered with the ExportChildObjects option, UnregisterNode
387 will unregister the child objects too.
388*/
389
390/*!
391 \since 4.8
392 \enum QDBusConnection::ConnectionCapability
393
394 This enum describes the available capabilities for a D-Bus connection.
395
396 \value UnixFileDescriptorPassing enables passing of Unix file descriptors to other processes
397 (see QDBusUnixFileDescriptor)
398
399 \sa connectionCapabilities()
400*/
401
402/*!
403 Creates a QDBusConnection object attached to the connection with name \a name.
404
405 This does not open the connection. You have to call connectToBus() to open it.
406*/
407QDBusConnection::QDBusConnection(const QString &name)
408{
409 if (name.isEmpty() || _q_manager.isDestroyed()) {
410 d = nullptr;
411 } else {
412 const auto locker = qt_scoped_lock(_q_manager()->mutex);
413 d = _q_manager()->connection(name);
414 if (d)
415 d->ref.ref();
416 }
417}
418
419/*!
420 Creates a copy of the \a other connection.
421*/
422QDBusConnection::QDBusConnection(const QDBusConnection &other)
423{
424 d = other.d;
425 if (d)
426 d->ref.ref();
427}
428
429/*!
430 \internal
431 Creates a connection object with the given \a dd as private object.
432*/
433QDBusConnection::QDBusConnection(QDBusConnectionPrivate *dd)
434{
435 d = dd;
436 if (d)
437 d->ref.ref();
438}
439
440/*!
441 Disposes of this object. This does not close the connection: you
442 have to call disconnectFromBus() to do that.
443*/
444QDBusConnection::~QDBusConnection()
445{
446 if (d && !d->ref.deref())
447 d->deleteLater();
448}
449
450/*!
451 Creates a copy of the connection \a other in this object. Note
452 that the connection this object referenced before the copy, is not
453 spontaneously disconnected.
454
455 \sa disconnectFromBus()
456*/
457QDBusConnection &QDBusConnection::operator=(const QDBusConnection &other)
458{
459 if (other.d)
460 other.d->ref.ref();
461 if (d && !d->ref.deref())
462 d->deleteLater();
463 d = other.d;
464 return *this;
465}
466
467/*!
468 Opens a connection of type \a type to one of the known busses and
469 associate with it the connection name \a name. Returns a
470 QDBusConnection object associated with that connection.
471*/
472QDBusConnection QDBusConnection::connectToBus(BusType type, const QString &name)
473{
474 if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
475 QDBusConnectionPrivate *d = nullptr;
476 return QDBusConnection(d);
477 }
478 return QDBusConnection(_q_manager()->connectToBus(type, name, false));
479}
480
481/*!
482 Opens a connection to a private bus on address \a address and associate with it the
483 connection name \a name. Returns a QDBusConnection object associated with that connection.
484*/
485QDBusConnection QDBusConnection::connectToBus(const QString &address,
486 const QString &name)
487{
488 if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
489 QDBusConnectionPrivate *d = nullptr;
490 return QDBusConnection(d);
491 }
492 return QDBusConnection(_q_manager()->connectToBus(address, name));
493}
494/*!
495 \since 4.8
496
497 Opens a peer-to-peer connection on address \a address and associate with it the
498 connection name \a name. Returns a QDBusConnection object associated with that connection.
499*/
500QDBusConnection QDBusConnection::connectToPeer(const QString &address,
501 const QString &name)
502{
503 if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
504 QDBusConnectionPrivate *d = nullptr;
505 return QDBusConnection(d);
506 }
507 return QDBusConnection(_q_manager()->connectToPeer(address, name));
508}
509
510/*!
511 Closes the bus connection of name \a name.
512
513 Note that if there are still QDBusConnection objects associated
514 with the same connection, the connection will not be closed until
515 all references are dropped. However, no further references can be
516 created using the QDBusConnection constructor.
517*/
518void QDBusConnection::disconnectFromBus(const QString &name)
519{
520 if (_q_manager()) {
521 const auto locker = qt_scoped_lock(_q_manager()->mutex);
522 QDBusConnectionPrivate *d = _q_manager()->connection(name);
523 if (d && d->mode != QDBusConnectionPrivate::ClientMode)
524 return;
525 _q_manager()->removeConnection(name);
526 }
527}
528
529/*!
530 \since 4.8
531
532 Closes the peer connection of name \a name.
533
534 Note that if there are still QDBusConnection objects associated
535 with the same connection, the connection will not be closed until
536 all references are dropped. However, no further references can be
537 created using the QDBusConnection constructor.
538*/
539void QDBusConnection::disconnectFromPeer(const QString &name)
540{
541 if (_q_manager()) {
542 const auto locker = qt_scoped_lock(_q_manager()->mutex);
543 QDBusConnectionPrivate *d = _q_manager()->connection(name);
544 if (d && d->mode != QDBusConnectionPrivate::PeerMode)
545 return;
546 _q_manager()->removeConnection(name);
547 }
548}
549
550/*!
551 Sends the \a message over this connection, without waiting for a
552 reply. This is suitable for errors, signals, and return values as
553 well as calls whose return values are not necessary.
554
555 Returns \c true if the message was queued successfully, false otherwise.
556*/
557bool QDBusConnection::send(const QDBusMessage &message) const
558{
559 if (!d || !d->connection) {
560 QDBusError err = QDBusError(QDBusError::Disconnected,
561 QDBusUtil::disconnectedErrorMessage());
562 if (d)
563 d->lastError = err;
564 return false;
565 }
566 return d->send(message);
567}
568
569/*!
570 Sends the \a message over this connection and returns immediately.
571 When the reply is received, the method \a returnMethod is called in
572 the \a receiver object. If an error occurs, the method \a errorMethod
573 will be called instead.
574
575 If no reply is received within \a timeout milliseconds, an automatic
576 error will be delivered indicating the expiration of the call.
577 The default \a timeout is -1, which will be replaced with an
578 implementation-defined value that is suitable for inter-process
579 communications (generally, 25 seconds).
580
581 This function is suitable for method calls only. It is guaranteed
582 that the slot will be called exactly once with the reply, as long
583 as the parameter types match and no error occurs.
584
585 Returns \c true if the message was sent, or false if the message could
586 not be sent.
587*/
588bool QDBusConnection::callWithCallback(const QDBusMessage &message, QObject *receiver,
589 const char *returnMethod, const char *errorMethod,
590 int timeout) const
591{
592 if (!d || !d->connection) {
593 QDBusError err = QDBusError(QDBusError::Disconnected,
594 QDBusUtil::disconnectedErrorMessage());
595 if (d)
596 d->lastError = err;
597 return false;
598 }
599 return d->sendWithReplyAsync(message, receiver, returnMethod, errorMethod, timeout) != nullptr;
600}
601
602/*!
603 \overload
604 \deprecated
605 Sends the \a message over this connection and returns immediately.
606 When the reply is received, the method \a returnMethod is called in
607 the \a receiver object.
608
609 This function is suitable for method calls only. It is guaranteed
610 that the slot will be called exactly once with the reply, as long
611 as the parameter types match and no error occurs.
612
613 This function is dangerous because it cannot report errors, including
614 the expiration of the timeout.
615
616 Returns \c true if the message was sent, or false if the message could
617 not be sent.
618*/
619bool QDBusConnection::callWithCallback(const QDBusMessage &message, QObject *receiver,
620 const char *returnMethod, int timeout) const
621{
622 return callWithCallback(message, receiver, returnMethod, nullptr, timeout);
623}
624
625/*!
626 Sends the \a message over this connection and blocks, waiting for
627 a reply, for at most \a timeout milliseconds. This function is
628 suitable for method calls only. It returns the reply message as
629 its return value, which will be either of type
630 QDBusMessage::ReplyMessage or QDBusMessage::ErrorMessage.
631
632 If no reply is received within \a timeout milliseconds, an automatic
633 error will be delivered indicating the expiration of the call.
634 The default \a timeout is -1, which will be replaced with an
635 implementation-defined value that is suitable for inter-process
636 communications (generally, 25 seconds).
637
638 See the QDBusInterface::call() function for a more friendly way
639 of placing calls.
640
641 \warning If \a mode is QDBus::BlockWithGui, this function will
642 reenter the Qt event loop in order to wait for the
643 reply. During the wait, it may deliver signals and other
644 method calls to your application. Therefore, it must be
645 prepared to handle a reentrancy whenever a call is
646 placed with call().
647*/
648QDBusMessage QDBusConnection::call(const QDBusMessage &message, QDBus::CallMode mode, int timeout) const
649{
650 if (!d || !d->connection) {
651 QDBusError err = QDBusError(QDBusError::Disconnected,
652 QDBusUtil::disconnectedErrorMessage());
653 if (d)
654 d->lastError = err;
655
656 return QDBusMessage::createError(err);
657 }
658
659 if (mode != QDBus::NoBlock)
660 return d->sendWithReply(message, mode, timeout);
661
662 d->send(message);
663 QDBusMessage retval;
664 retval << QVariant(); // add one argument (to avoid .at(0) problems)
665 return retval;
666}
667
668/*!
669 \since 4.5
670 Sends the \a message over this connection and returns
671 immediately. This function is suitable for method calls only. It
672 returns an object of type QDBusPendingCall which can be used to
673 track the status of the reply.
674
675 If no reply is received within \a timeout milliseconds, an automatic
676 error will be delivered indicating the expiration of the call. The
677 default \a timeout is -1, which will be replaced with an
678 implementation-defined value that is suitable for inter-process
679 communications (generally, 25 seconds). This timeout is also the
680 upper limit for waiting in QDBusPendingCall::waitForFinished().
681
682 See the QDBusInterface::asyncCall() function for a more friendly way
683 of placing calls.
684*/
685QDBusPendingCall QDBusConnection::asyncCall(const QDBusMessage &message, int timeout) const
686{
687 if (!d || !d->connection) {
688 return QDBusPendingCall(nullptr); // null pointer -> disconnected
689 }
690
691 QDBusPendingCallPrivate *priv = d->sendWithReplyAsync(message, nullptr, nullptr, nullptr, timeout);
692 return QDBusPendingCall(priv);
693}
694
695/*!
696 Connects the signal specified by the \a service, \a path, \a interface and \a name parameters to
697 the slot \a slot in object \a receiver. The arguments \a service and \a path can be empty,
698 denoting a connection to any signal of the (\a interface, \a name) pair, from any remote
699 application.
700
701 Returns \c true if the connection was successful.
702
703 \warning The signal will only be delivered to the slot if the parameters match. This verification
704 can be done only when the signal is received, not at connection time.
705*/
706bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
707 const QString &name, QObject *receiver, const char *slot)
708{
709 return connect(service, path, interface, name, QStringList(), QString(), receiver, slot);
710}
711
712/*!
713 \overload
714
715 Connects the signal to the slot \a slot in object \a
716 receiver. Unlike the previous connect() overload, this function
717 allows one to specify the parameter signature to be connected
718 using the \a signature variable. The function will then verify
719 that this signature can be delivered to the slot specified by \a
720 slot and return false otherwise.
721
722 Returns \c true if the connection was successful.
723
724 \note This function verifies that the signal signature matches the
725 slot's parameters, but it does not verify that the actual
726 signal exists with the given signature in the remote
727 service.
728*/
729bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
730 const QString &name, const QString &signature,
731 QObject *receiver, const char *slot)
732{
733 return connect(service, path, interface, name, QStringList(), signature, receiver, slot);
734}
735
736/*!
737 \overload
738 \since 4.6
739
740 Connects the signal to the slot \a slot in object \a
741 receiver. Unlike the previous connect() overload, this function
742 allows one to specify the parameter signature to be connected
743 using the \a signature variable. The function will then verify
744 that this signature can be delivered to the slot specified by \a
745 slot and return false otherwise.
746
747 The \a argumentMatch parameter lists the string parameters to be matched,
748 in sequential order. Note that, to match an empty string, you need to
749 pass a QString that is empty but not null (i.e., QString("")). A null
750 QString skips matching at that position.
751
752 Returns \c true if the connection was successful.
753
754 \note This function verifies that the signal signature matches the
755 slot's parameters, but it does not verify that the actual
756 signal exists with the given signature in the remote
757 service.
758*/
759bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
760 const QString &name, const QStringList &argumentMatch, const QString &signature,
761 QObject *receiver, const char *slot)
762{
763
764 if (!receiver || !slot || !d || !d->connection)
765 return false;
766 if (interface.isEmpty() && name.isEmpty())
767 return false;
768 if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) {
769#ifndef QT_NO_DEBUG
770 qWarning("QDBusConnection::connect: interface name '%s' is not valid", interface.toLatin1().constData());
771#endif
772 return false;
773 }
774 if (!service.isEmpty() && !QDBusUtil::isValidBusName(service)) {
775#ifndef QT_NO_DEBUG
776 qWarning("QDBusConnection::connect: service name '%s' is not valid", service.toLatin1().constData());
777#endif
778 return false;
779 }
780 if (!path.isEmpty() && !QDBusUtil::isValidObjectPath(path)) {
781#ifndef QT_NO_DEBUG
782 qWarning("QDBusConnection::connect: object path '%s' is not valid", path.toLatin1().constData());
783#endif
784 return false;
785 }
786
787 return d->connectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot);
788}
789
790/*!
791 Disconnects the signal specified by the \a service, \a path, \a interface
792 and \a name parameters from the slot \a slot in object \a receiver. The
793 arguments must be the same as passed to the connect() function.
794
795 Returns \c true if the disconnection was successful.
796*/
797bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString &interface,
798 const QString &name, QObject *receiver, const char *slot)
799{
800 return disconnect(service, path, interface, name, QStringList(), QString(), receiver, slot);
801}
802
803/*!
804 \overload
805
806 Disconnects the signal specified by the \a service, \a path, \a
807 interface, \a name, and \a signature parameters from the slot \a slot in
808 object \a receiver. The arguments must be the same as passed to the
809 connect() function.
810
811 Returns \c true if the disconnection was successful.
812*/
813bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString& interface,
814 const QString &name, const QString &signature,
815 QObject *receiver, const char *slot)
816{
817 return disconnect(service, path, interface, name, QStringList(), signature, receiver, slot);
818}
819
820/*!
821 \overload
822 \since 4.6
823
824 Disconnects the signal specified by the \a service, \a path, \a
825 interface, \a name, \a argumentMatch, and \a signature parameters from
826 the slot \a slot in object \a receiver. The arguments must be the same as
827 passed to the connect() function.
828
829 Returns \c true if the disconnection was successful.
830*/
831bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString& interface,
832 const QString &name, const QStringList &argumentMatch, const QString &signature,
833 QObject *receiver, const char *slot)
834{
835 if (!receiver || !slot || !d || !d->connection)
836 return false;
837 if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface))
838 return false;
839 if (interface.isEmpty() && name.isEmpty())
840 return false;
841
842 return d->disconnectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot);
843}
844
845/*!
846 Registers the object \a object at path \a path and returns \c true if
847 the registration was successful. The \a options parameter
848 specifies how much of the object \a object will be exposed through
849 D-Bus.
850
851 This function does not replace existing objects: if there is already an object registered at
852 path \a path, this function will return false. Use unregisterObject() to unregister it first.
853
854 The ExportChildObjects flag exports child objects on D-Bus based on the
855 path of the registered objects and the QObject::objectName of the child.
856 Therefore, it is important for the child object to have an object name.
857
858 You cannot register an object as a child object of an object that
859 was registered with ExportChildObjects.
860*/
861bool QDBusConnection::registerObject(const QString &path, QObject *object, RegisterOptions options)
862{
863 return registerObject(path, QString(), object, options);
864}
865
866/*!
867 \overload
868 \since 5.5
869
870 Registers the object \a object at path \a path with interface name \a interface
871 and returns \c true if the registration was successful. The \a options parameter
872 specifies how much of the object \a object will be exposed through
873 D-Bus.
874
875 This function does not replace existing objects: if there is already an object registered at
876 path \a path, this function will return false. Use unregisterObject() to unregister it first.
877
878 The ExportChildObjects flag exports child objects on D-Bus based on the
879 path of the registered objects and the QObject::objectName of the child.
880 Therefore, it is important for the child object to have an object name.
881
882 You cannot register an object as a child object of an object that
883 was registered with ExportChildObjects.
884*/
885bool QDBusConnection::registerObject(const QString &path, const QString &interface, QObject *object, RegisterOptions options)
886{
887 Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), "QDBusConnection::registerObject",
888 "Invalid object path given");
889 if (!d || !d->connection || !object || !options || !QDBusUtil::isValidObjectPath(path))
890 return false;
891
892 auto pathComponents = QStringView{path}.split(QLatin1Char('/'));
893 if (pathComponents.constLast().isEmpty())
894 pathComponents.removeLast();
895 QDBusWriteLocker locker(RegisterObjectAction, d);
896
897 // lower-bound search for where this object should enter in the tree
898 QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator node = &d->rootNode;
899 int i = 1;
900 while (node) {
901 if (pathComponents.count() == i) {
902 // this node exists
903 // consider it free if there's no object here and the user is not trying to
904 // replace the object sub-tree
905 if (node->obj)
906 return false;
907
908 if (options & QDBusConnectionPrivate::VirtualObject) {
909 if (options & SubPath && !node->children.isEmpty())
910 return false;
911 } else {
912 if ((options & ExportChildObjects && !node->children.isEmpty()))
913 return false;
914 }
915 // we can add the object here
916 node->obj = object;
917 node->flags = options;
918 node->interfaceName = interface;
919
920 d->registerObject(node);
921 //qDebug("REGISTERED FOR %s", path.toLocal8Bit().constData());
922 return true;
923 }
924
925 // if a virtual object occupies this path, return false
926 if (node->obj && (node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath)) {
927 //qDebug("Cannot register object at %s because QDBusVirtualObject handles all sub-paths.",
928 // qPrintable(path));
929 return false;
930 }
931
932 // find the position where we'd insert the node
933 QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it =
934 std::lower_bound(node->children.begin(), node->children.end(), pathComponents.at(i));
935 if (it != node->children.end() && it->name == pathComponents.at(i)) {
936 // match: this node exists
937 node = it;
938
939 // are we allowed to go deeper?
940 if (node->flags & ExportChildObjects) {
941 // we're not
942 //qDebug("Cannot register object at %s because %s exports its own child objects",
943 // qPrintable(path), qPrintable(pathComponents.at(i)));
944 return false;
945 }
946 } else {
947 // add entry
948 node = node->children.insert(it, pathComponents.at(i).toString());
949 }
950
951 // iterate
952 ++i;
953 }
954
955 Q_ASSERT_X(false, "QDBusConnection::registerObject", "The impossible happened");
956 return false;
957}
958
959/*!
960 \internal
961 \since 4.8
962 Registers a QDBusTreeNode for a path. It can handle a path including all child paths, thus
963 handling multiple DBus nodes.
964
965 To unregister a QDBusTreeNode use the unregisterObject() function with its path.
966*/
967bool QDBusConnection::registerVirtualObject(const QString &path, QDBusVirtualObject *treeNode,
968 VirtualObjectRegisterOption options)
969{
970 int opts = options | QDBusConnectionPrivate::VirtualObject;
971 return registerObject(path, (QObject*) treeNode, (RegisterOptions) opts);
972}
973
974/*!
975 Unregisters an object that was registered with the registerObject() at the object path given by
976 \a path and, if \a mode is QDBusConnection::UnregisterTree, all of its sub-objects too.
977
978 Note that you cannot unregister objects that were not registered with registerObject().
979*/
980void QDBusConnection::unregisterObject(const QString &path, UnregisterMode mode)
981{
982 if (!d || !d->connection || !QDBusUtil::isValidObjectPath(path))
983 return;
984
985 QDBusWriteLocker locker(UnregisterObjectAction, d);
986 d->unregisterObject(path, mode);
987}
988
989/*!
990 Return the object that was registered with the registerObject() at the object path given by
991 \a path.
992*/
993QObject *QDBusConnection::objectRegisteredAt(const QString &path) const
994{
995 Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), "QDBusConnection::registeredObject",
996 "Invalid object path given");
997 if (!d || !d->connection || !QDBusUtil::isValidObjectPath(path))
998 return nullptr;
999
1000 auto pathComponents = QStringView{path}.split(QLatin1Char('/'));
1001 if (pathComponents.constLast().isEmpty())
1002 pathComponents.removeLast();
1003
1004 // lower-bound search for where this object should enter in the tree
1005 QDBusReadLocker lock(ObjectRegisteredAtAction, d);
1006 const QDBusConnectionPrivate::ObjectTreeNode *node = &d->rootNode;
1007
1008 int i = 1;
1009 while (node) {
1010 if (pathComponents.count() == i)
1011 return node->obj;
1012 if ((node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath))
1013 return node->obj;
1014
1015 QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it =
1016 std::lower_bound(node->children.constBegin(), node->children.constEnd(), pathComponents.at(i));
1017 if (it == node->children.constEnd() || it->name != pathComponents.at(i))
1018 break; // node not found
1019
1020 node = it;
1021 ++i;
1022 }
1023 return nullptr;
1024}
1025
1026
1027
1028/*!
1029 Returns a QDBusConnectionInterface object that represents the
1030 D-Bus server interface on this connection.
1031*/
1032QDBusConnectionInterface *QDBusConnection::interface() const
1033{
1034 if (!d || d->mode != QDBusConnectionPrivate::ClientMode)
1035 return nullptr;
1036 return d->busService;
1037}
1038
1039/*!
1040 \internal
1041 \since 4.8
1042
1043 Returns the internal, implementation-defined pointer for this
1044 connection. Currently, this returns a DBusConnection* pointer,
1045 without changing the reference count. It is the responsibility of
1046 the caller to call dbus_connection_ref if it wants to store the
1047 pointer.
1048*/
1049void *QDBusConnection::internalPointer() const
1050{
1051 return d ? d->connection : nullptr;
1052}
1053
1054/*!
1055 Returns \c true if this QDBusConnection object is connected.
1056*/
1057bool QDBusConnection::isConnected() const
1058{
1059 return d && d->connection && q_dbus_connection_get_is_connected(d->connection);
1060}
1061
1062/*!
1063 Returns the last error that happened in this connection.
1064
1065 This function is provided for low-level code. If you're using
1066 QDBusInterface::call(), error codes are reported by its return
1067 value.
1068
1069 \sa QDBusInterface, QDBusMessage
1070*/
1071QDBusError QDBusConnection::lastError() const
1072{
1073 return d ? d->lastError : QDBusError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
1074}
1075
1076/*!
1077 Returns the unique connection name for this connection, if this QDBusConnection object is
1078 connected, or an empty QString otherwise.
1079
1080 A Unique Connection Name is a string in the form ":x.xxx" (where x
1081 are decimal digits) that is assigned by the D-Bus server daemon
1082 upon connection. It uniquely identifies this client in the bus.
1083
1084 This function returns an empty QString for peer-to-peer connections.
1085*/
1086QString QDBusConnection::baseService() const
1087{
1088 return d ? d->baseService : QString();
1089}
1090
1091/*!
1092 \since 4.5
1093
1094 Returns the connection name for this connection, as given as the
1095 name parameter to connectToBus().
1096
1097 The connection name can be used to uniquely identify actual
1098 underlying connections to buses. Copies made from a single
1099 connection will always implicitly share the underlying connection,
1100 and hence will have the same connection name.
1101
1102 Inversely, two connections having different connection names will
1103 always either be connected to different buses, or have a different
1104 unique name (as returned by baseService()) on that bus.
1105
1106 \sa connectToBus(), disconnectFromBus()
1107*/
1108QString QDBusConnection::name() const
1109{
1110 return d ? d->name : QString();
1111}
1112
1113/*!
1114 \since 4.8
1115
1116 Returns the capabilities of this connection as negotiated with the bus
1117 server or peer. If this QDBusConnection is not connected, this function
1118 returns no capabilities.
1119*/
1120QDBusConnection::ConnectionCapabilities QDBusConnection::connectionCapabilities() const
1121{
1122 return d ? d->connectionCapabilities() : ConnectionCapabilities();
1123}
1124
1125/*!
1126 Attempts to register the \a serviceName on the D-Bus server and
1127 returns \c true if the registration succeeded. The registration will
1128 fail if the name is already registered by another application.
1129
1130 \sa unregisterService(), QDBusConnectionInterface::registerService()
1131*/
1132bool QDBusConnection::registerService(const QString &serviceName)
1133{
1134 if (interface() && interface()->registerService(serviceName)) {
1135 if (d) d->registerService(serviceName);
1136 return true;
1137 }
1138 return false;
1139}
1140
1141/*!
1142 Unregisters the service \a serviceName that was previously
1143 registered with registerService() and returns \c true if it
1144 succeeded.
1145
1146 \sa registerService(), QDBusConnectionInterface::unregisterService()
1147*/
1148bool QDBusConnection::unregisterService(const QString &serviceName)
1149{
1150 if (interface()->unregisterService(serviceName)) {
1151 if (d) d->unregisterService(serviceName);
1152 return true;
1153 }
1154 return false;
1155}
1156
1157/*!
1158 \fn QDBusConnection QDBusConnection::sessionBus()
1159
1160 Returns a QDBusConnection object opened with the session bus. The object
1161 reference returned by this function is valid until the application terminates,
1162 at which point the connection will be closed and the object deleted.
1163*/
1164QDBusConnection QDBusConnection::sessionBus()
1165{
1166 if (_q_manager.isDestroyed())
1167 return QDBusConnection(nullptr);
1168 return QDBusConnection(_q_manager()->busConnection(SessionBus));
1169}
1170
1171/*!
1172 \fn QDBusConnection QDBusConnection::systemBus()
1173
1174 Returns a QDBusConnection object opened with the system bus. The object reference returned
1175 by this function is valid until the QCoreApplication's destructor is run, when the
1176 connection will be closed and the object, deleted.
1177*/
1178QDBusConnection QDBusConnection::systemBus()
1179{
1180 if (_q_manager.isDestroyed())
1181 return QDBusConnection(nullptr);
1182 return QDBusConnection(_q_manager()->busConnection(SystemBus));
1183}
1184
1185/*!
1186 \internal
1187*/
1188void QDBusConnectionPrivate::createBusService()
1189{
1190 Q_ASSERT(mode == ClientMode);
1191 QDBusConnection connection(this);
1192 busService = new QDBusConnectionInterface(connection, this);
1193 ref.deref(); // busService has increased the refcounting to us
1194 // avoid cyclic refcounting
1195
1196 QObject::connect(this, &QDBusConnectionPrivate::callWithCallbackFailed,
1197 busService, emit &QDBusConnectionInterface::callWithCallbackFailed,
1198 Qt::QueuedConnection);
1199}
1200
1201/*!
1202 \since 4.8
1203 Returns the local machine ID as known to the D-Bus system. Each
1204 node or host that runs D-Bus has a unique identifier that can be
1205 used to distinguish it from other hosts if they are sharing
1206 resources like the filesystem.
1207
1208 Note that the local machine ID is not guaranteed to be persistent
1209 across boots of the system, so this identifier should not be
1210 stored in persistent storage (like the filesystem). It is
1211 guaranteed to remain constant only during the lifetime of this
1212 boot session.
1213*/
1214QByteArray QDBusConnection::localMachineId()
1215{
1216 char *dbus_machine_id = q_dbus_get_local_machine_id();
1217 QByteArray result = dbus_machine_id;
1218 q_dbus_free(dbus_machine_id);
1219 return result;
1220}
1221
1222/*!
1223 \namespace QDBus
1224 \inmodule QtDBus
1225
1226 \brief The QDBus namespace contains miscellaneous identifiers used
1227 throughout the Qt D-Bus module.
1228*/
1229
1230/*!
1231 \enum QDBus::CallMode
1232
1233 This enum describes the various ways of placing a function call. The valid modes are:
1234
1235 \value NoBlock Place the call but don't wait for the reply (the reply's contents
1236 will be discarded).
1237 \value Block Don't use an event loop to wait for a reply, but instead block on
1238 network operations while waiting. This means the
1239 user-interface may not be updated until the function returns.
1240 \value BlockWithGui Use the Qt event loop to wait for a reply. This means that the
1241 user-interface will stay responsive (processing input events),
1242 but it also means other events may happen, like signal delivery
1243 and other D-Bus method calls.
1244 \value AutoDetect Automatically detect if the called function has a reply.
1245
1246 When using BlockWithGui, applications must be prepared for reentrancy in any function.
1247*/
1248
1249/*!
1250 \fn void QDBusConnection::swap(QDBusConnection &other)
1251
1252 Swaps this QDBusConnection instance with \a other.
1253*/
1254
1255QT_END_NAMESPACE
1256
1257#ifdef Q_OS_WIN
1258# include <qt_windows.h>
1259
1260QT_BEGIN_NAMESPACE
1261static void preventDllUnload()
1262{
1263 // Thread termination is really wacky on Windows. For some reason we don't
1264 // understand, exiting from the thread may try to unload the DLL. Since the
1265 // QDBusConnectionManager thread runs until the DLL is unloaded, we've got
1266 // a deadlock: the main thread is waiting for the manager thread to exit,
1267 // but the manager thread is attempting to acquire a lock to unload the DLL.
1268 //
1269 // We work around the issue by preventing the unload from happening in the
1270 // first place.
1271 //
1272 // For this trick, see
1273 // https://blogs.msdn.microsoft.com/oldnewthing/20131105-00/?p=2733
1274
1275 static HMODULE self;
1276 GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
1277 GET_MODULE_HANDLE_EX_FLAG_PIN,
1278 reinterpret_cast<const wchar_t *>(&self), // any address in this DLL
1279 &self);
1280}
1281QT_END_NAMESPACE
1282#endif
1283
1284#endif // QT_NO_DBUS
1285