Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdbusconnection_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the public API. This header file may
11// change from version to version without notice, or even be
12// removed.
13//
14// We mean it.
15//
16//
17
18#ifndef QDBUSCONNECTION_P_H
19#define QDBUSCONNECTION_P_H
20
21#include <QtDBus/private/qtdbusglobal_p.h>
22#include <qdbuserror.h>
23#include <qdbusconnection.h>
24
25#include <QtCore/qatomic.h>
26#include <QtCore/qhash.h>
27#include <QtCore/qlist.h>
28#include <QtCore/qobject.h>
29#include <QtCore/qpointer.h>
30#include <QtCore/qreadwritelock.h>
31#include <QtCore/qstringlist.h>
32#include <QtCore/qvarlengtharray.h>
33
35
36#include <qdbusmessage.h>
37#include <qdbusservicewatcher.h> // for the WatchMode enum
38Q_MOC_INCLUDE(<QtDBus/private/qdbuspendingcall_p.h>)
39
40#ifndef QT_NO_DBUS
41
42QT_BEGIN_NAMESPACE
43
44class QDBusMessage;
45class QSocketNotifier;
46class QTimerEvent;
47class QDBusObjectPrivate;
48class QDBusCallDeliveryEvent;
50class QMetaMethod;
52struct QDBusMetaObject;
53class QDBusAbstractInterface;
54class QDBusConnectionInterface;
56class QDBusServer;
57
58#ifndef QT_BOOTSTRAPPED
59
61{
62 mutable DBusError error;
64public:
67 inline bool operator !() const { return !q_dbus_error_is_set(&error); }
68 inline operator DBusError *() { q_dbus_error_free(&error); return &error; }
70};
71
72// QDBusConnectionPrivate holds the DBusConnection and
73// can have many QDBusConnection objects referring to it
74
75class Q_AUTOTEST_EXPORT QDBusConnectionPrivate: public QObject
76{
77 Q_OBJECT
78public:
79 // structs and enums
80 enum ConnectionMode { InvalidMode, ServerMode, ClientMode, PeerMode }; // LocalMode
81
82 struct Watcher
83 {
84 Watcher(): watch(nullptr), read(nullptr), write(nullptr) {}
85 DBusWatch *watch;
86 QSocketNotifier *read;
87 QSocketNotifier *write;
88 };
89
90 struct ArgMatchRules {
91 QStringList args;
92 QString arg0namespace;
93 bool operator==(const ArgMatchRules &other) const {
94 return args == other.args &&
95 arg0namespace == other.arg0namespace;
96 }
97 };
98
99 struct SignalHook
100 {
101 inline SignalHook() : obj(nullptr), midx(-1) { }
102 QString service, path, signature;
103 QObject* obj;
104 int midx;
105 QList<QMetaType> params;
106 ArgMatchRules argumentMatch;
107 QByteArray matchRule;
108 };
109
110 enum TreeNodeType {
111 Object = 0x0,
112 VirtualObject = 0x01000000
113 };
114
115 struct ObjectTreeNode
116 {
117 typedef QList<ObjectTreeNode> DataList;
118
119 inline ObjectTreeNode() : obj(nullptr) { }
120 inline ObjectTreeNode(const QString &n) // intentionally implicit
121 : name(n), obj(nullptr)
122 {
123 }
124 inline bool operator<(const QString &other) const
125 { return name < other; }
126 inline bool operator<(QStringView other) const
127 { return name < other; }
128 inline bool isActive() const
129 { return obj || !children.isEmpty(); }
130
131 QString name;
132 QString interfaceName;
133 union {
134 QObject *obj;
135 QDBusVirtualObject *treeNode;
136 };
137 QDBusConnection::RegisterOptions flags;
138
139 DataList children;
140 };
141
142 // typedefs
143 typedef QMultiHash<qintptr, Watcher> WatcherHash;
144 typedef QHash<int, DBusTimeout *> TimeoutHash;
145 typedef QList<QDBusMessage> PendingMessageList;
146
147 typedef QMultiHash<QString, SignalHook> SignalHookHash;
148 typedef QHash<QString, QDBusMetaObject* > MetaObjectHash;
149 typedef QHash<QByteArray, int> MatchRefCountHash;
150 typedef QList<QDBusPendingCallPrivate *> PendingCallList;
151
152 struct WatchedServiceData {
153 WatchedServiceData() : refcount(0) {}
154 WatchedServiceData(const QString &owner, int refcount = 0)
155 : owner(owner), refcount(refcount)
156 {}
157 QString owner;
158 int refcount;
159 };
160 typedef QHash<QString, WatchedServiceData> WatchedServicesHash;
161
162 // public methods are entry points from other objects
163 QDBusConnectionPrivate();
164 ~QDBusConnectionPrivate();
165
166 void createBusService();
167 void setPeer(DBusConnection *connection, const QDBusErrorInternal &error);
168 void setConnection(DBusConnection *connection, const QDBusErrorInternal &error);
169 void setServer(QDBusServer *object, DBusServer *server, const QDBusErrorInternal &error);
170 void closeConnection();
171
172 QString getNameOwner(const QString &service);
173
174 bool shouldWatchService(const QString &service);
175 void watchService(const QString &service, QDBusServiceWatcher::WatchMode mode,
176 QObject *obj, const char *member);
177 void unwatchService(const QString &service, QDBusServiceWatcher::WatchMode mode,
178 QObject *obj, const char *member);
179
180 bool send(const QDBusMessage &message);
181 QDBusMessage sendWithReply(const QDBusMessage &message, QDBus::CallMode mode, int timeout = -1);
182 QDBusMessage sendWithReplyLocal(const QDBusMessage &message);
183 QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
184 const char *returnMethod, const char *errorMethod,int timeout = -1);
185
186 bool connectSignal(const QString &service, const QString &path, const QString& interface,
187 const QString &name, const QStringList &argumentMatch, const QString &signature,
188 QObject *receiver, const char *slot);
189 bool disconnectSignal(const QString &service, const QString &path, const QString& interface,
190 const QString &name, const QStringList &argumentMatch, const QString &signature,
191 QObject *receiver, const char *slot);
192 bool connectSignal(const QString &service, const QString &path, const QString& interface,
193 const QString &name, const ArgMatchRules &argumentMatch, const QString &signature,
194 QObject *receiver, const char *slot);
195 bool disconnectSignal(const QString &service, const QString &path, const QString& interface,
196 const QString &name, const ArgMatchRules &argumentMatch, const QString &signature,
197 QObject *receiver, const char *slot);
198 void registerObject(const ObjectTreeNode *node);
199 void unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode);
200 void connectRelay(const QString &service,
201 const QString &path, const QString &interface,
202 QDBusAbstractInterface *receiver, const QMetaMethod &signal);
203 void disconnectRelay(const QString &service,
204 const QString &path, const QString &interface,
205 QDBusAbstractInterface *receiver, const QMetaMethod &signal);
206 void registerService(const QString &serviceName);
207 void unregisterService(const QString &serviceName);
208
209 bool handleMessage(const QDBusMessage &msg);
210
211 QDBusMetaObject *findMetaObject(const QString &service, const QString &path,
212 const QString &interface, QDBusError &error);
213
214 void postEventToThread(int action, QObject *target, QEvent *event);
215
216 void enableDispatchDelayed(QObject *context);
217
218private:
219 void checkThread();
220 bool handleError(const QDBusErrorInternal &error);
221
222 void handleSignal(const QString &key, const QDBusMessage &msg);
223 void handleSignal(const QDBusMessage &msg);
224 void handleObjectCall(const QDBusMessage &message);
225
226 void activateSignal(const SignalHook& hook, const QDBusMessage &msg);
227 void activateObject(ObjectTreeNode &node, const QDBusMessage &msg, int pathStartPos);
228 bool activateInternalFilters(const ObjectTreeNode &node, const QDBusMessage &msg);
229 bool activateCall(QObject *object, QDBusConnection::RegisterOptions flags,
230 const QDBusMessage &msg);
231
232 void sendInternal(QDBusPendingCallPrivate *pcall, void *msg, int timeout);
233 void sendError(const QDBusMessage &msg, QDBusError::ErrorType code);
234 void deliverCall(QObject *object, const QDBusMessage &msg, const QList<QMetaType> &metaTypes,
235 int slotIdx);
236
237 SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it);
238 void collectAllObjects(ObjectTreeNode &node, QSet<QObject *> &set);
239
240 bool isServiceRegisteredByThread(const QString &serviceName);
241
242 QString getNameOwnerNoCache(const QString &service);
243
244 void watchForDBusDisconnection();
245
246 void handleAuthentication();
247
248 bool addSignalHook(const QString &key, const SignalHook &hook);
249 bool removeSignalHook(const QString &key, const SignalHook &hook);
250
251 bool addSignalHookImpl(const QString &key, const SignalHook &hook);
252 bool removeSignalHookImpl(const QString &key, const SignalHook &hook);
253
254protected:
255 void timerEvent(QTimerEvent *e) override;
256
257public slots:
258 // public slots
259 void setDispatchEnabled(bool enable);
260 void doDispatch();
261 void socketRead(qintptr);
262 void socketWrite(qintptr);
263 void objectDestroyed(QObject *o);
264 void relaySignal(QObject *obj, const QMetaObject *, int signalId, const QVariantList &args);
265
266private slots:
267 void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner);
268 void registerServiceNoLock(const QString &serviceName);
269 void unregisterServiceNoLock(const QString &serviceName);
270 void handleDBusDisconnection();
271
272signals:
273 void dispatchStatusChanged();
274 void spyHooksFinished(const QDBusMessage &msg);
275 void messageNeedsSending(QDBusPendingCallPrivate *pcall, void *msg, int timeout = -1);
276 void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
277 void callWithCallbackFailed(const QDBusError &error, const QDBusMessage &message);
278
279public:
280 static constexpr QDBusConnection::ConnectionCapabilities ConnectionIsBus =
281 QDBusConnection::ConnectionCapabilities::fromInt(0x8000'0000);
282 static constexpr QDBusConnection::ConnectionCapabilities InternalCapabilitiesMask = ConnectionIsBus;
283
284 QAtomicInt ref;
285 QAtomicInt capabilities;
286 QDBusConnection::ConnectionCapabilities connectionCapabilities() const
287 {
288 uint capa = capabilities.loadRelaxed();
289 if (mode == ClientMode)
290 capa |= ConnectionIsBus;
291 return QDBusConnection::ConnectionCapabilities(capa);
292 }
293 QString name; // this connection's name
294 QString baseService; // this connection's base service
295 QStringList serverConnectionNames;
296
297 ConnectionMode mode;
298 union {
299 QDBusConnectionInterface *busService;
300 QDBusServer *serverObject;
301 };
302
303 union {
304 DBusConnection *connection;
305 DBusServer *server;
306 };
307 WatcherHash watchers;
308 TimeoutHash timeouts;
309 PendingMessageList pendingMessages;
310
311 // the master lock protects our own internal state
312 QReadWriteLock lock;
313 QDBusError lastError;
314
315 QStringList serviceNames;
316 WatchedServicesHash watchedServices;
317 SignalHookHash signalHooks;
318 MatchRefCountHash matchRefCounts;
319 ObjectTreeNode rootNode;
320 MetaObjectHash cachedMetaObjects;
321 PendingCallList pendingCalls;
322
323 bool anonymousAuthenticationAllowed;
324 bool dispatchEnabled; // protected by the dispatch lock, not the main lock
325 bool isAuthenticated;
326
327 // static methods
328 static int findSlot(QObject *obj, const QByteArray &normalizedName, QList<QMetaType> &params,
329 QString &errorMsg);
330 static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
331 const QString &service, const QString &path, const QString &interface,
332 const QString &name, const ArgMatchRules &argMatch, QObject *receiver,
333 const char *signal, int minMIdx, bool buildSignature,
334 QString &errorMsg);
335 static QDBusCallDeliveryEvent *prepareReply(QDBusConnectionPrivate *target, QObject *object,
336 int idx, const QList<QMetaType> &metaTypes,
337 const QDBusMessage &msg);
338 static void processFinishedCall(QDBusPendingCallPrivate *call);
339
340 static QDBusConnectionPrivate *d(const QDBusConnection& q) { return q.d; }
341 static QDBusConnection q(QDBusConnectionPrivate *connection) { return QDBusConnection(connection); }
342
343 friend class QDBusActivateObjectEvent;
344 friend class QDBusCallDeliveryEvent;
345 friend class QDBusServer;
346};
347
348// in qdbusmisc.cpp
349extern int qDBusParametersForMethod(const QMetaMethod &mm, QList<QMetaType> &metaTypes, QString &errorMsg);
350# endif // QT_BOOTSTRAPPED
351extern Q_DBUS_EXPORT int qDBusParametersForMethod(const QList<QByteArray> &parameters,
352 QList<QMetaType> &metaTypes, QString &errorMsg);
353extern Q_DBUS_EXPORT bool qDBusCheckAsyncTag(const char *tag);
354#ifndef QT_BOOTSTRAPPED
355extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name);
356extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo);
357
358// in qdbusinternalfilters.cpp
359extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node, const QString &path);
360extern QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node,
361 const QDBusMessage &msg);
362extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node,
363 const QDBusMessage &msg);
364extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node,
365 const QDBusMessage &msg);
366
367#endif // QT_BOOTSTRAPPED
368
369QT_END_NAMESPACE
370
371#endif // QT_NO_DBUS
372#endif
static void saveIntrospectionXml(QDBusAbstractAdaptor *adaptor, const QString &xml)
static QString retrieveIntrospectionXml(QDBusAbstractAdaptor *adaptor)
void relay(QObject *sender, int id, void **)
void addAdaptor(QDBusAbstractAdaptor *adaptor)
void disconnectAllSignals(QObject *object)
QList< AdaptorData > AdaptorMap
QDBusAdaptorConnector(QObject *parent)
void connectAllSignals(QObject *object)
\inmodule QtDBus
CallMode
This enum describes the various ways of placing a function call.
QDBusAdaptorConnector * qDBusFindAdaptorConnector(QDBusAbstractAdaptor *adaptor)
QDBusAdaptorConnector * qDBusCreateAdaptorConnector(QObject *obj)
QDBusAdaptorConnector * qDBusFindAdaptorConnector(QObject *obj)
QDBusAdaptorConnector * qDBusCreateAdaptorConnector(QObject *object)
#define QCLASSINFO_DBUS_INTERFACE
QDBusAdaptorConnector * qDBusFindAdaptorConnector(QObject *object)
bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name)
Q_DBUS_EXPORT int qDBusParametersForMethod(const QList< QByteArray > &parameters, QList< QMetaType > &metaTypes, QString &errorMsg)
QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node, const QString &path)
QString qDBusInterfaceFromMetaObject(const QMetaObject *mo)
Definition qdbusmisc.cpp:43
Q_DBUS_EXPORT bool qDBusCheckAsyncTag(const char *tag)
Definition qdbusmisc.cpp:26
QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg)
QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg)
int qDBusParametersForMethod(const QMetaMethod &mm, QList< QMetaType > &metaTypes, QString &errorMsg)
QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg)
Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_RELOCATABLE_TYPE)