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

Last change on this file since 603 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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