PageRenderTime 28ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/qt/qtbase/src/dbus/qdbusconnection.cpp

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