Qt 4.8
qdbusconnection_p.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDBus module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 //
43 // W A R N I N G
44 // -------------
45 //
46 // This file is not part of the public API. This header file may
47 // change from version to version without notice, or even be
48 // removed.
49 //
50 // We mean it.
51 //
52 //
53 
54 #ifndef QDBUSCONNECTION_P_H
55 #define QDBUSCONNECTION_P_H
56 
57 #include <qdbuserror.h>
58 #include <qdbusconnection.h>
59 
60 #include <QtCore/qatomic.h>
61 #include <QtCore/qhash.h>
62 #include <QtCore/qmutex.h>
63 #include <QtCore/qobject.h>
64 #include <QtCore/qpointer.h>
65 #include <QtCore/qreadwritelock.h>
66 #include <QtCore/qstringlist.h>
67 #include <QtCore/qvarlengtharray.h>
68 #include <QtCore/qvector.h>
69 
70 #include "qdbus_symbols_p.h"
71 
72 #include <qdbusmessage.h>
73 
74 #ifndef QT_NO_DBUS
75 
77 
78 class QDBusMessage;
79 class QSocketNotifier;
80 class QTimerEvent;
81 class QDBusObjectPrivate;
84 class QMetaMethod;
86 struct QDBusMetaObject;
90 
92 {
93  mutable DBusError error;
95 public:
96  inline QDBusErrorInternal() { q_dbus_error_init(&error); }
97  inline ~QDBusErrorInternal() { q_dbus_error_free(&error); }
98  inline bool operator !() const { return !q_dbus_error_is_set(&error); }
99  inline operator DBusError *() { q_dbus_error_free(&error); return &error; }
100  inline operator QDBusError() const { QDBusError err(&error); q_dbus_error_free(&error); return err; }
101 };
102 
103 // QDBusConnectionPrivate holds the DBusConnection and
104 // can have many QDBusConnection objects referring to it
105 
107 {
108  Q_OBJECT
109 public:
110  // structs and enums
111  enum ConnectionMode { InvalidMode, ServerMode, ClientMode, PeerMode }; // LocalMode
112 
113  struct Watcher
114  {
115  Watcher(): watch(0), read(0), write(0) {}
116  DBusWatch *watch;
119  };
120 
121  struct SignalHook
122  {
123  inline SignalHook() : obj(0), midx(-1) { }
124  QString service, path, signature;
126  int midx;
130  };
131 
133  Object = 0x0,
134  VirtualObject = 0x01000000
135  };
136 
138  {
140 
141  inline ObjectTreeNode() : obj(0), flags(0) { }
142  inline ObjectTreeNode(const QString &n) // intentionally implicit
143  : name(n), obj(0), flags(0) { }
144  inline ~ObjectTreeNode() { }
145  inline bool operator<(const QString &other) const
146  { return name < other; }
147  inline bool operator<(const QStringRef &other) const
148  { return QStringRef(&name) < other; }
149 
151  union {
154  };
155  int flags;
156 
157  DataList children;
158  };
159 
160 public:
161  // typedefs
165 
169 
173  : owner(owner), refcount(refcount)
174  {}
176  int refcount;
177  };
179 
180 public:
181  // public methods are entry points from other objects
182  explicit QDBusConnectionPrivate(QObject *parent = 0);
184  void deleteYourself();
185 
186  void setBusService(const QDBusConnection &connection);
187  void setPeer(DBusConnection *connection, const QDBusErrorInternal &error);
188  void setConnection(DBusConnection *connection, const QDBusErrorInternal &error);
189  void setServer(DBusServer *server, const QDBusErrorInternal &error);
190  void closeConnection();
191 
192  QString getNameOwner(const QString &service);
193 
194  int send(const QDBusMessage &message);
195  QDBusMessage sendWithReply(const QDBusMessage &message, int mode, int timeout = -1);
196  QDBusMessage sendWithReplyLocal(const QDBusMessage &message);
197  QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
198  const char *returnMethod, const char *errorMethod,int timeout = -1);
199  bool connectSignal(const QString &service, const QString &path, const QString& interface,
200  const QString &name, const QStringList &argumentMatch, const QString &signature,
201  QObject *receiver, const char *slot);
202  void connectSignal(const QString &key, const SignalHook &hook);
203  SignalHookHash::Iterator disconnectSignal(SignalHookHash::Iterator &it);
204  bool disconnectSignal(const QString &service, const QString &path, const QString& interface,
205  const QString &name, const QStringList &argumentMatch, const QString &signature,
206  QObject *receiver, const char *slot);
207  void registerObject(const ObjectTreeNode *node);
208  void connectRelay(const QString &service,
209  const QString &path, const QString &interface,
210  QDBusAbstractInterface *receiver, const char *signal);
211  void disconnectRelay(const QString &service,
212  const QString &path, const QString &interface,
213  QDBusAbstractInterface *receiver, const char *signal);
214  void registerService(const QString &serviceName);
215  void unregisterService(const QString &serviceName);
216 
217  bool handleMessage(const QDBusMessage &msg);
218  void waitForFinished(QDBusPendingCallPrivate *pcall);
219 
220  QDBusMetaObject *findMetaObject(const QString &service, const QString &path,
221  const QString &interface, QDBusError &error);
222 
223  void postEventToThread(int action, QObject *target, QEvent *event);
224 
225  inline void serverConnection(const QDBusConnection &connection)
226  { emit newServerConnection(connection); }
227 
228 private:
229  void checkThread();
230  bool handleError(const QDBusErrorInternal &error);
231 
232  void handleSignal(const QString &key, const QDBusMessage &msg);
233  void handleSignal(const QDBusMessage &msg);
234  void handleObjectCall(const QDBusMessage &message);
235 
236  void activateSignal(const SignalHook& hook, const QDBusMessage &msg);
237  void activateObject(ObjectTreeNode &node, const QDBusMessage &msg, int pathStartPos);
238  bool activateInternalFilters(const ObjectTreeNode &node, const QDBusMessage &msg);
239  bool activateCall(QObject *object, int flags, const QDBusMessage &msg);
240 
241  void sendError(const QDBusMessage &msg, QDBusError::ErrorType code);
242  void deliverCall(QObject *object, int flags, const QDBusMessage &msg,
243  const QList<int> &metaTypes, int slotIdx);
244 
245  bool isServiceRegisteredByThread(const QString &serviceName) const;
246 
247  QString getNameOwnerNoCache(const QString &service);
248 
249 protected:
250  void customEvent(QEvent *e);
251  void timerEvent(QTimerEvent *e);
252 
253 public slots:
254  // public slots
255  void doDispatch();
256  void socketRead(int);
257  void socketWrite(int);
258  void objectDestroyed(QObject *o);
259  void relaySignal(QObject *obj, const QMetaObject *, int signalId, const QVariantList &args);
260 
261 private slots:
262  void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner);
263  void registerServiceNoLock(const QString &serviceName);
264  void unregisterServiceNoLock(const QString &serviceName);
265 
266 signals:
267  void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
268  void callWithCallbackFailed(const QDBusError &error, const QDBusMessage &message);
269  void newServerConnection(const QDBusConnection &connection);
270 
271 public:
273  QDBusConnection::ConnectionCapabilities capabilities;
274  QString name; // this connection's name
275  QString baseService; // this connection's base service
277 
279 
280  // members accessed in unlocked mode (except for deletion)
281  // connection and server provide their own locking mechanisms
282  // busService doesn't have state to be changed
283  DBusConnection *connection;
284  DBusServer *server;
286 
287  // watchers and timeouts are accessed from any thread
288  // but the corresponding timer and QSocketNotifier must be handled
289  // only in the object's thread
291  WatcherHash watchers;
292  TimeoutHash timeouts;
293  PendingTimeoutList timeoutsPendingAdd;
294 
295  // members accessed through a lock
299 
301  WatchedServicesHash watchedServices;
302  SignalHookHash signalHooks;
303  MatchRefCountHash matchRefCounts;
305  MetaObjectHash cachedMetaObjects;
306 
308  QDBusCallDeliveryEvent *callDeliveryState; // protected by the callDeliveryMutex mutex
309 
310 public:
311  // static methods
312  static int findSlot(QObject *obj, const QByteArray &normalizedName, QList<int>& params);
313  static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
314  const QString &service,
315  const QString &path, const QString &interface, const QString &name,
316  const QStringList &argMatch,
317  QObject *receiver, const char *signal, int minMIdx,
318  bool buildSignature);
319  static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *);
320  static bool checkReplyForDelivery(QDBusConnectionPrivate *target, QObject *object,
321  int idx, const QList<int> &metaTypes,
322  const QDBusMessage &msg);
323  static QDBusCallDeliveryEvent *prepareReply(QDBusConnectionPrivate *target, QObject *object,
324  int idx, const QList<int> &metaTypes,
325  const QDBusMessage &msg);
326  static void processFinishedCall(QDBusPendingCallPrivate *call);
327 
328  static QDBusConnectionPrivate *d(const QDBusConnection& q) { return q.d; }
329  static QDBusConnection q(QDBusConnectionPrivate *connection) { return QDBusConnection(connection); }
330 
331  static void setSender(const QDBusConnectionPrivate *s);
332 
335 };
336 
337 // in qdbusmisc.cpp
339 extern int qDBusNameToTypeId(const char *name);
340 extern bool qDBusCheckAsyncTag(const char *tag);
341 extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name);
343 
344 // in qdbusinternalfilters.cpp
347  const QDBusMessage &msg);
349  const QDBusMessage &msg);
351  const QDBusMessage &msg);
352 
354 
355 #endif // QT_NO_DBUS
356 #endif
QHash< QString, WatchedServiceData > WatchedServicesHash
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
The QDBusConnectionInterface class provides access to the D-Bus bus daemon service.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
The QMutex class provides access serialization between threads.
Definition: qmutex.h:60
EventRef event
QMultiHash< QString, SignalHook > SignalHookHash
The QAtomicInt class provides platform-independent atomic operations on integers. ...
Definition: qatomic.h:55
#define it(className, varName)
static int refcount
Definition: proxyconf.cpp:398
static QDBusConnectionPrivate * d(const QDBusConnection &q)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
The QDBusError class represents an error received from the D-Bus bus or from remote applications foun...
Definition: qdbuserror.h:60
#define Q_DISABLE_COPY(Class)
Disables the use of copy constructors and assignment operators for the given Class.
Definition: qglobal.h:2523
static QDBusConnection q(QDBusConnectionPrivate *connection)
MatchRefCountHash matchRefCounts
The QString class provides a Unicode character string.
Definition: qstring.h:83
static QWidget * owner
QHash< int, DBusTimeout * > TimeoutHash
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags, const QString &signature_, QList< int > &metaTypes)
DBusConnection * connection
MetaObjectHash cachedMetaObjects
QHash< QString, QDBusMetaObject *> MetaObjectHash
bool qDBusCheckAsyncTag(const char *tag)
Definition: qdbusmisc.cpp:57
int qDBusParametersForMethod(const QMetaMethod &mm, QList< int > &metaTypes)
Definition: qdbusmisc.cpp:137
ErrorType
In order to facilitate verification of the most common D-Bus errors generated by the D-Bus implementa...
Definition: qdbuserror.h:63
The QSocketNotifier class provides support for monitoring activity on a file descriptor.
The QDBusAbstractInterface class is the base class for all D-Bus interfaces in the QtDBus binding...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QString qDBusInterfaceFromMetaObject(const QMetaObject *mo)
Definition: qdbusmisc.cpp:80
WatchedServiceData(const QString &owner, int refcount=0)
const char * name
#define emit
Definition: qobjectdefs.h:76
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
QMultiHash< int, Watcher > WatcherHash
bool operator<(const QStringRef &other) const
QDBusConnection::ConnectionCapabilities capabilities
The QDBusVirtualObject class is used to handle several DBus paths with one class. ...
QDBusConnectionPrivate * d
#define Q_OBJECT
Definition: qobjectdefs.h:157
QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg)
The QStringRef class provides a thin wrapper around QString substrings.
Definition: qstring.h:1099
PendingTimeoutList timeoutsPendingAdd
bool operator<(const QString &other) const
QHash< QByteArray, int > MatchRefCountHash
int qDBusNameToTypeId(const char *name)
Definition: qdbusmisc.cpp:72
QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg)
QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg)
static QAuServer & server()
Definition: qsound.cpp:79
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:341
The QDBusConnection class represents a connection to the D-Bus bus daemon.
The QReadWriteLock class provides read-write locking.
bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name)
Definition: qdbusmisc.cpp:116
WatchedServicesHash watchedServices
int key
QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node, const QString &path)
The QDBusMessage class represents one message sent or received over the D-Bus bus.
Definition: qdbusmessage.h:59
bool operator!() const
QList< QPair< DBusTimeout *, int > > PendingTimeoutList
QDBusCallDeliveryEvent * callDeliveryState
QDBusConnectionInterface * busService
#define slots
Definition: qobjectdefs.h:68
#define signals
Definition: qobjectdefs.h:69
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:56
void serverConnection(const QDBusConnection &connection)