author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Tue, 02 Feb 2010 00:43:10 +0200 | |
changeset 3 | 41300fa6a67c |
parent 0 | 1918ee327afb |
child 4 | 3b1da2848fc7 |
permissions | -rw-r--r-- |
0 | 1 |
/**************************************************************************** |
2 |
** |
|
3 |
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 |
** All rights reserved. |
|
5 |
** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 |
** |
|
7 |
** This file is part of the QtDBus module of the Qt Toolkit. |
|
8 |
** |
|
9 |
** $QT_BEGIN_LICENSE:LGPL$ |
|
10 |
** No Commercial Usage |
|
11 |
** This file contains pre-release code and may not be distributed. |
|
12 |
** You may use this file in accordance with the terms and conditions |
|
13 |
** contained in the Technology Preview License Agreement accompanying |
|
14 |
** this package. |
|
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 |
** If you have questions regarding the use of this file, please contact |
|
29 |
** Nokia at qt-info@nokia.com. |
|
30 |
** |
|
31 |
** |
|
32 |
** |
|
33 |
** |
|
34 |
** |
|
35 |
** |
|
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 |
||
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
70 |
#include "qdbus_symbols_p.h" |
0 | 71 |
|
72 |
#include <qdbusmessage.h> |
|
73 |
||
74 |
QT_BEGIN_NAMESPACE |
|
75 |
||
76 |
class QDBusMessage; |
|
77 |
class QSocketNotifier; |
|
78 |
class QTimerEvent; |
|
79 |
class QDBusObjectPrivate; |
|
80 |
class QDBusCallDeliveryEvent; |
|
81 |
class QDBusActivateObjectEvent; |
|
82 |
class QMetaMethod; |
|
83 |
class QDBusInterfacePrivate; |
|
84 |
struct QDBusMetaObject; |
|
85 |
class QDBusAbstractInterface; |
|
86 |
class QDBusConnectionInterface; |
|
87 |
class QDBusPendingCallPrivate; |
|
88 |
||
89 |
class QDBusErrorInternal |
|
90 |
{ |
|
91 |
mutable DBusError error; |
|
92 |
Q_DISABLE_COPY(QDBusErrorInternal) |
|
93 |
public: |
|
94 |
inline QDBusErrorInternal() { q_dbus_error_init(&error); } |
|
95 |
inline ~QDBusErrorInternal() { q_dbus_error_free(&error); } |
|
96 |
inline bool operator !() const { return !q_dbus_error_is_set(&error); } |
|
97 |
inline operator DBusError *() { q_dbus_error_free(&error); return &error; } |
|
98 |
inline operator QDBusError() const { QDBusError err(&error); q_dbus_error_free(&error); return err; } |
|
99 |
}; |
|
100 |
||
101 |
// QDBusConnectionPrivate holds the DBusConnection and |
|
102 |
// can have many QDBusConnection objects referring to it |
|
103 |
||
104 |
class QDBusConnectionPrivate: public QObject |
|
105 |
{ |
|
106 |
Q_OBJECT |
|
107 |
public: |
|
108 |
// structs and enums |
|
109 |
enum ConnectionMode { InvalidMode, ServerMode, ClientMode, PeerMode }; // LocalMode |
|
110 |
||
111 |
struct Watcher |
|
112 |
{ |
|
113 |
Watcher(): watch(0), read(0), write(0) {} |
|
114 |
DBusWatch *watch; |
|
115 |
QSocketNotifier *read; |
|
116 |
QSocketNotifier *write; |
|
117 |
}; |
|
118 |
||
119 |
struct SignalHook |
|
120 |
{ |
|
121 |
inline SignalHook() : obj(0), midx(-1) { } |
|
122 |
QString owner, service, path, signature; |
|
123 |
QObject* obj; |
|
124 |
int midx; |
|
125 |
QList<int> params; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
126 |
QStringList argumentMatch; |
0 | 127 |
QByteArray matchRule; |
128 |
}; |
|
129 |
||
130 |
struct ObjectTreeNode |
|
131 |
{ |
|
132 |
typedef QVector<ObjectTreeNode> DataList; |
|
133 |
||
134 |
inline ObjectTreeNode() : obj(0), flags(0) { } |
|
135 |
inline ObjectTreeNode(const QString &n) // intentionally implicit |
|
136 |
: name(n), obj(0), flags(0) { } |
|
137 |
inline ~ObjectTreeNode() { } |
|
138 |
inline bool operator<(const QString &other) const |
|
139 |
{ return name < other; } |
|
140 |
inline bool operator<(const QStringRef &other) const |
|
141 |
{ return QStringRef(&name) < other; } |
|
142 |
||
143 |
QString name; |
|
144 |
QObject* obj; |
|
145 |
int flags; |
|
146 |
DataList children; |
|
147 |
}; |
|
148 |
||
149 |
public: |
|
150 |
// typedefs |
|
151 |
typedef QMultiHash<int, Watcher> WatcherHash; |
|
152 |
typedef QHash<int, DBusTimeout *> TimeoutHash; |
|
153 |
typedef QList<QPair<DBusTimeout *, int> > PendingTimeoutList; |
|
154 |
||
155 |
typedef QMultiHash<QString, SignalHook> SignalHookHash; |
|
156 |
typedef QHash<QString, QDBusMetaObject* > MetaObjectHash; |
|
157 |
typedef QHash<QByteArray, int> MatchRefCountHash; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
158 |
typedef QHash<QString, int> WatchedServicesHash; |
0 | 159 |
|
160 |
public: |
|
161 |
// public methods are entry points from other objects |
|
162 |
explicit QDBusConnectionPrivate(QObject *parent = 0); |
|
163 |
~QDBusConnectionPrivate(); |
|
164 |
void deleteYourself(); |
|
165 |
||
166 |
void setBusService(const QDBusConnection &connection); |
|
167 |
void setPeer(DBusConnection *connection, const QDBusErrorInternal &error); |
|
168 |
void setConnection(DBusConnection *connection, const QDBusErrorInternal &error); |
|
169 |
void setServer(DBusServer *server, const QDBusErrorInternal &error); |
|
170 |
void closeConnection(); |
|
171 |
||
172 |
QString getNameOwner(const QString &service); |
|
173 |
||
174 |
int send(const QDBusMessage &message); |
|
175 |
QDBusMessage sendWithReply(const QDBusMessage &message, int mode, int timeout = -1); |
|
176 |
QDBusMessage sendWithReplyLocal(const QDBusMessage &message); |
|
177 |
QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, int timeout = -1); |
|
178 |
int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, |
|
179 |
const char *returnMethod, const char *errorMethod, int timeout = -1); |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
180 |
bool connectSignal(const QString &service, const QString &owner, const QString &path, const QString& interface, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
181 |
const QString &name, const QStringList &argumentMatch, const QString &signature, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
182 |
QObject *receiver, const char *slot); |
0 | 183 |
void connectSignal(const QString &key, const SignalHook &hook); |
184 |
SignalHookHash::Iterator disconnectSignal(SignalHookHash::Iterator &it); |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
185 |
bool disconnectSignal(const QString &service, const QString &path, const QString& interface, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
186 |
const QString &name, const QStringList &argumentMatch, const QString &signature, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
187 |
QObject *receiver, const char *slot); |
0 | 188 |
void registerObject(const ObjectTreeNode *node); |
189 |
void connectRelay(const QString &service, const QString ¤tOwner, |
|
190 |
const QString &path, const QString &interface, |
|
191 |
QDBusAbstractInterface *receiver, const char *signal); |
|
192 |
void disconnectRelay(const QString &service, const QString ¤tOwner, |
|
193 |
const QString &path, const QString &interface, |
|
194 |
QDBusAbstractInterface *receiver, const char *signal); |
|
195 |
||
196 |
bool handleMessage(const QDBusMessage &msg); |
|
197 |
void waitForFinished(QDBusPendingCallPrivate *pcall); |
|
198 |
||
199 |
QDBusMetaObject *findMetaObject(const QString &service, const QString &path, |
|
200 |
const QString &interface, QDBusError &error); |
|
201 |
||
202 |
void postEventToThread(int action, QObject *target, QEvent *event); |
|
203 |
||
204 |
inline void serverConnection(const QDBusConnection &connection) |
|
205 |
{ emit newServerConnection(connection); } |
|
206 |
||
207 |
private: |
|
208 |
void checkThread(); |
|
209 |
bool handleError(const QDBusErrorInternal &error); |
|
210 |
||
211 |
void handleSignal(const QString &key, const QDBusMessage &msg); |
|
212 |
void handleSignal(const QDBusMessage &msg); |
|
213 |
void handleObjectCall(const QDBusMessage &message); |
|
214 |
||
215 |
void activateSignal(const SignalHook& hook, const QDBusMessage &msg); |
|
216 |
void activateObject(ObjectTreeNode &node, const QDBusMessage &msg, int pathStartPos); |
|
217 |
bool activateInternalFilters(const ObjectTreeNode &node, const QDBusMessage &msg); |
|
218 |
bool activateCall(QObject *object, int flags, const QDBusMessage &msg); |
|
219 |
||
220 |
void sendError(const QDBusMessage &msg, QDBusError::ErrorType code); |
|
221 |
void deliverCall(QObject *object, int flags, const QDBusMessage &msg, |
|
222 |
const QList<int> &metaTypes, int slotIdx); |
|
223 |
||
224 |
bool isServiceRegisteredByThread(const QString &serviceName) const; |
|
225 |
||
226 |
protected: |
|
227 |
void customEvent(QEvent *e); |
|
228 |
void timerEvent(QTimerEvent *e); |
|
229 |
||
230 |
public slots: |
|
231 |
// public slots |
|
232 |
void doDispatch(); |
|
233 |
void socketRead(int); |
|
234 |
void socketWrite(int); |
|
235 |
void objectDestroyed(QObject *o); |
|
236 |
void relaySignal(QObject *obj, const QMetaObject *, int signalId, const QVariantList &args); |
|
237 |
void _q_serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
238 |
void registerService(const QString &serviceName); |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
239 |
void unregisterService(const QString &serviceName); |
0 | 240 |
|
241 |
signals: |
|
242 |
void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); |
|
243 |
void callWithCallbackFailed(const QDBusError &error, const QDBusMessage &message); |
|
244 |
void newServerConnection(const QDBusConnection &connection); |
|
245 |
||
246 |
public: |
|
247 |
QAtomicInt ref; |
|
248 |
QString name; // this connection's name |
|
249 |
QString baseService; // this connection's base service |
|
250 |
||
251 |
ConnectionMode mode; |
|
252 |
||
253 |
// members accessed in unlocked mode (except for deletion) |
|
254 |
// connection and server provide their own locking mechanisms |
|
255 |
// busService doesn't have state to be changed |
|
256 |
DBusConnection *connection; |
|
257 |
DBusServer *server; |
|
258 |
QDBusConnectionInterface *busService; |
|
259 |
||
260 |
// watchers and timeouts are accessed from any thread |
|
261 |
// but the corresponding timer and QSocketNotifier must be handled |
|
262 |
// only in the object's thread |
|
263 |
QMutex watchAndTimeoutLock; |
|
264 |
WatcherHash watchers; |
|
265 |
TimeoutHash timeouts; |
|
266 |
PendingTimeoutList timeoutsPendingAdd; |
|
267 |
||
268 |
// members accessed through a lock |
|
269 |
QMutex dispatchLock; |
|
270 |
QReadWriteLock lock; |
|
271 |
QDBusError lastError; |
|
272 |
||
273 |
QStringList serviceNames; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
274 |
WatchedServicesHash watchedServiceNames; |
0 | 275 |
SignalHookHash signalHooks; |
276 |
MatchRefCountHash matchRefCounts; |
|
277 |
ObjectTreeNode rootNode; |
|
278 |
MetaObjectHash cachedMetaObjects; |
|
279 |
||
280 |
QMutex callDeliveryMutex; |
|
281 |
QDBusCallDeliveryEvent *callDeliveryState; // protected by the callDeliveryMutex mutex |
|
282 |
||
283 |
public: |
|
284 |
// static methods |
|
285 |
static int findSlot(QObject *obj, const QByteArray &normalizedName, QList<int>& params); |
|
286 |
static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key, |
|
287 |
const QString &service, const QString &owner, |
|
288 |
const QString &path, const QString &interface, const QString &name, |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
289 |
const QStringList &argMatch, |
0 | 290 |
QObject *receiver, const char *signal, int minMIdx, |
291 |
bool buildSignature); |
|
292 |
static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *); |
|
293 |
static QDBusCallDeliveryEvent *prepareReply(QDBusConnectionPrivate *target, QObject *object, |
|
294 |
int idx, const QList<int> &metaTypes, |
|
295 |
const QDBusMessage &msg); |
|
296 |
static void processFinishedCall(QDBusPendingCallPrivate *call); |
|
297 |
||
298 |
static QDBusConnectionPrivate *d(const QDBusConnection& q) { return q.d; } |
|
299 |
static QDBusConnection q(QDBusConnectionPrivate *connection) { return QDBusConnection(connection); } |
|
300 |
||
301 |
static void setSender(const QDBusConnectionPrivate *s); |
|
302 |
static void setConnection(const QString &name, QDBusConnectionPrivate *c); |
|
303 |
||
304 |
friend class QDBusActivateObjectEvent; |
|
305 |
friend class QDBusCallDeliveryEvent; |
|
306 |
}; |
|
307 |
||
308 |
// in qdbusmisc.cpp |
|
309 |
extern int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& metaTypes); |
|
310 |
extern int qDBusNameToTypeId(const char *name); |
|
311 |
extern bool qDBusCheckAsyncTag(const char *tag); |
|
312 |
extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name); |
|
313 |
extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo); |
|
314 |
||
315 |
// in qdbusinternalfilters.cpp |
|
316 |
extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node); |
|
317 |
extern QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node, |
|
318 |
const QDBusMessage &msg); |
|
319 |
extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node, |
|
320 |
const QDBusMessage &msg); |
|
321 |
extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node, |
|
322 |
const QDBusMessage &msg); |
|
323 |
||
324 |
QT_END_NAMESPACE |
|
325 |
||
326 |
#endif |