source: trunk/src/dbus/qdbusconnection.cpp@ 1023

Last change on this file since 1023 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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