80 enum ConnectionMode { InvalidMode, ServerMode, ClientMode, PeerMode };
84 Watcher(): watch(
nullptr), read(
nullptr), write(
nullptr) {}
86 QSocketNotifier *read;
87 QSocketNotifier *write;
90 struct ArgMatchRules {
92 QString arg0namespace;
93 bool operator==(
const ArgMatchRules &other)
const {
94 return args == other.args &&
95 arg0namespace == other.arg0namespace;
101 inline SignalHook() : obj(
nullptr), midx(-1) { }
102 QString service, path, signature;
105 QList<QMetaType> params;
106 ArgMatchRules argumentMatch;
107 QByteArray matchRule;
112 VirtualObject = 0x01000000
115 struct ObjectTreeNode
117 typedef QList<ObjectTreeNode> DataList;
119 inline ObjectTreeNode() : obj(
nullptr) { }
120 inline ObjectTreeNode(
const QString &n)
121 : name(n), obj(
nullptr)
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(); }
132 QString interfaceName;
135 QDBusVirtualObject *treeNode;
137 QDBusConnection::RegisterOptions flags;
143 typedef QMultiHash<qintptr, Watcher> WatcherHash;
144 typedef QHash<
int, DBusTimeout *> TimeoutHash;
145 typedef QList<QDBusMessage> PendingMessageList;
147 typedef QMultiHash<QString, SignalHook> SignalHookHash;
148 typedef QHash<QString, QDBusMetaObject* > MetaObjectHash;
149 typedef QHash<QByteArray,
int> MatchRefCountHash;
150 typedef QList<QDBusPendingCallPrivate *> PendingCallList;
152 struct WatchedServiceData {
153 WatchedServiceData() : refcount(0) {}
154 WatchedServiceData(
const QString &owner,
int refcount = 0)
155 : owner(owner), refcount(refcount)
160 typedef QHash<QString, WatchedServiceData> WatchedServicesHash;
163 QDBusConnectionPrivate();
164 ~QDBusConnectionPrivate();
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();
172 QString getNameOwner(
const QString &service);
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);
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);
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);
209 bool handleMessage(
const QDBusMessage &msg);
211 QDBusMetaObject *findMetaObject(
const QString &service,
const QString &path,
212 const QString &interface, QDBusError &error);
214 void postEventToThread(
int action, QObject *target, QEvent *event);
216 void enableDispatchDelayed(QObject *context);
220 bool handleError(
const QDBusErrorInternal &error);
222 void handleSignal(
const QString &key,
const QDBusMessage &msg);
223 void handleSignal(
const QDBusMessage &msg);
224 void handleObjectCall(
const QDBusMessage &message);
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);
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,
237 SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it);
238 void collectAllObjects(ObjectTreeNode &node, QSet<QObject *> &set);
240 bool isServiceRegisteredByThread(
const QString &serviceName);
242 QString getNameOwnerNoCache(
const QString &service);
244 void watchForDBusDisconnection();
246 void handleAuthentication();
248 bool addSignalHook(
const QString &key,
const SignalHook &hook);
249 bool removeSignalHook(
const QString &key,
const SignalHook &hook);
251 bool addSignalHookImpl(
const QString &key,
const SignalHook &hook);
252 bool removeSignalHookImpl(
const QString &key,
const SignalHook &hook);
255 void timerEvent(QTimerEvent *e) override;
259 void setDispatchEnabled(
bool enable);
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);
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();
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);
280 static constexpr QDBusConnection::ConnectionCapabilities ConnectionIsBus =
281 QDBusConnection::ConnectionCapabilities::fromInt(0x8000'0000);
282 static constexpr QDBusConnection::ConnectionCapabilities InternalCapabilitiesMask = ConnectionIsBus;
285 QAtomicInt capabilities;
286 QDBusConnection::ConnectionCapabilities connectionCapabilities()
const
288 uint capa = capabilities.loadRelaxed();
289 if (mode == ClientMode)
290 capa |= ConnectionIsBus;
291 return QDBusConnection::ConnectionCapabilities(capa);
295 QStringList serverConnectionNames;
299 QDBusConnectionInterface *busService;
300 QDBusServer *serverObject;
304 DBusConnection *connection;
307 WatcherHash watchers;
308 TimeoutHash timeouts;
309 PendingMessageList pendingMessages;
313 QDBusError lastError;
315 QStringList serviceNames;
316 WatchedServicesHash watchedServices;
317 SignalHookHash signalHooks;
318 MatchRefCountHash matchRefCounts;
319 ObjectTreeNode rootNode;
320 MetaObjectHash cachedMetaObjects;
321 PendingCallList pendingCalls;
323 bool anonymousAuthenticationAllowed;
324 bool dispatchEnabled;
325 bool isAuthenticated;
328 static int findSlot(QObject *obj,
const QByteArray &normalizedName, QList<QMetaType> ¶ms,
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,
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);
340 static QDBusConnectionPrivate *d(
const QDBusConnection& q) {
return q.d; }
341 static QDBusConnection q(QDBusConnectionPrivate *connection) {
return QDBusConnection(connection); }
343 friend class QDBusActivateObjectEvent;
344 friend class QDBusCallDeliveryEvent;
345 friend class QDBusServer;