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