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
qdbusmessage.cpp
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
5#include "qdbusmessage.h"
7
8#include <qdebug.h>
9#include <qstringlist.h>
10
12
14#include "qdbuserror.h"
15#include "qdbusmetatype.h"
17#include "qdbusutil_p.h"
18
19#ifndef QT_NO_DBUS
20
22
23using namespace Qt::StringLiterals;
24
26
27static_assert(QDBusMessage::InvalidMessage == DBUS_MESSAGE_TYPE_INVALID);
28static_assert(QDBusMessage::MethodCallMessage == DBUS_MESSAGE_TYPE_METHOD_CALL);
29static_assert(QDBusMessage::ReplyMessage == DBUS_MESSAGE_TYPE_METHOD_RETURN);
30static_assert(QDBusMessage::ErrorMessage == DBUS_MESSAGE_TYPE_ERROR);
31static_assert(QDBusMessage::SignalMessage == DBUS_MESSAGE_TYPE_SIGNAL);
32
33static inline const char *data(const QByteArray &arr)
34{
35 return arr.isEmpty() ? nullptr : arr.constData();
36}
37
45
50
52{
53 if (Q_UNLIKELY(call->type != QDBusMessage::MethodCallMessage)) {
54 qWarning("QDBusMessage: replying to a message that isn't a method call");
55 return;
56 }
57
58 if (call->localMessage) {
59 localMessage = true;
60 call->localReply = new QDBusMessage(*this); // keep an internal copy
61 } else {
62 serial = call->serial;
63 service = call->service;
64 }
65
66 // the reply must have a serial or be a local-loop optimization
67 Q_ASSERT(serial || localMessage);
68}
69
70/*!
71 \since 4.3
72 Returns the human-readable message associated with the error that was received.
73*/
74QString QDBusMessage::errorMessage() const
75{
76 if (d_ptr->type == ErrorMessage) {
77 if (!d_ptr->message.isEmpty())
78 return d_ptr->message;
79 if (!d_ptr->arguments.isEmpty())
80 return d_ptr->arguments.at(0).toString();
81 }
82 return QString();
83}
84
85/*!
86 \internal
87 Constructs a DBusMessage object from \a message. The returned value must be de-referenced
88 with q_dbus_message_unref. The \a capabilities flags indicates which capabilities to use.
89
90 The \a error object is set to indicate the error if anything went wrong with the
91 marshalling. Usually, this error message will be placed in the reply, as if the call failed.
92 The \a error pointer must not be null.
93*/
94DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusConnection::ConnectionCapabilities capabilities,
95 QDBusError *error)
96{
98 *error = QDBusError(QDBusError::Failed, "Could not open lidbus-1 library"_L1);
99 return nullptr;
100 }
101
102 DBusMessage *msg = nullptr;
103 const QDBusMessagePrivate *d_ptr = message.d_ptr;
104
105 switch (d_ptr->type) {
106 case QDBusMessage::InvalidMessage:
107 //qDebug() << "QDBusMessagePrivate::toDBusMessage" << "message is invalid";
108 break;
109 case QDBusMessage::MethodCallMessage:
110 // only service and interface can be empty -> path and name must not be empty
111 if (!d_ptr->parametersValidated) {
112 using namespace QDBusUtil;
113 AllowEmptyFlag serviceCheckMode = capabilities & QDBusConnectionPrivate::ConnectionIsBus
114 ? EmptyNotAllowed : EmptyAllowed;
115 if (!checkBusName(d_ptr->service, serviceCheckMode, error))
116 return nullptr;
117 if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error))
118 return nullptr;
119 if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error))
120 return nullptr;
121 if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method"))
122 return nullptr;
123 }
124
125 msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(),
126 data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8());
127 q_dbus_message_set_auto_start( msg, d_ptr->autoStartService );
128 q_dbus_message_set_allow_interactive_authorization(msg, d_ptr->interactiveAuthorizationAllowed);
129
130 break;
131 case QDBusMessage::ReplyMessage:
132 msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
133 if (!d_ptr->localMessage) {
134 q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8()));
135 q_dbus_message_set_reply_serial(msg, d_ptr->serial);
136 }
137 break;
138 case QDBusMessage::ErrorMessage:
139 // error name can't be empty
140 if (!d_ptr->parametersValidated
141 && !QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error))
142 return nullptr;
143
144 msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
145 q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8());
146 if (!d_ptr->localMessage) {
147 q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8()));
148 q_dbus_message_set_reply_serial(msg, d_ptr->serial);
149 }
150 break;
151 case QDBusMessage::SignalMessage:
152 // only the service name can be empty here (even for bus connections)
153 if (!d_ptr->parametersValidated) {
154 if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error))
155 return nullptr;
156 if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error))
157 return nullptr;
158 if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error))
159 return nullptr;
160 if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method"))
161 return nullptr;
162 }
163
164 msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(),
165 d_ptr->name.toUtf8());
166 q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8()));
167 break;
168 }
169
170 // if we got here, the parameters validated
171 // and since the message parameters cannot be changed once the message is created
172 // we can record this fact
173 d_ptr->parametersValidated = true;
174
175 QDBusMarshaller marshaller(capabilities);
176 q_dbus_message_iter_init_append(msg, &marshaller.iterator);
177 if (!d_ptr->message.isEmpty())
178 // prepend the error message
179 marshaller.append(d_ptr->message);
180 for (const QVariant &argument : std::as_const(d_ptr->arguments))
181 marshaller.appendVariantInternal(argument);
182
183 // check if everything is ok
184 if (marshaller.ok)
185 return msg;
186
187 // not ok;
188 q_dbus_message_unref(msg);
189 *error = QDBusError(QDBusError::Failed, "Marshalling failed: "_L1 + marshaller.errorString);
190 return nullptr;
191}
192
193/*
194struct DBusMessage
195{
196 DBusAtomic refcount;
197 DBusHeader header;
198 DBusString body;
199 char byte_order;
200 unsigned int locked : 1;
201DBUS_DISABLE_CHECKS
202 unsigned int in_cache : 1;
203#endif
204 DBusList *size_counters;
205 long size_counter_delta;
206 dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
207 DBusDataSlotList slot_list;
208#ifndef DBUS_DISABLE_CHECKS
209 int generation;
210#endif
211};
212*/
213
214/*!
215 \internal
216 Constructs a QDBusMessage by parsing the given DBusMessage object.
217*/
218QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnection::ConnectionCapabilities capabilities)
219{
220 QDBusMessage message;
221 if (!dmsg)
222 return message;
223
224 message.d_ptr->type = QDBusMessage::MessageType(q_dbus_message_get_type(dmsg));
225 message.d_ptr->serial = q_dbus_message_get_serial(dmsg);
226 message.d_ptr->path = QString::fromUtf8(q_dbus_message_get_path(dmsg));
227 message.d_ptr->interface = QString::fromUtf8(q_dbus_message_get_interface(dmsg));
228 message.d_ptr->name = message.d_ptr->type == DBUS_MESSAGE_TYPE_ERROR ?
229 QString::fromUtf8(q_dbus_message_get_error_name(dmsg)) :
230 QString::fromUtf8(q_dbus_message_get_member(dmsg));
231 message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
232 message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
233 message.d_ptr->interactiveAuthorizationAllowed = q_dbus_message_get_allow_interactive_authorization(dmsg);
234 message.d_ptr->isReplyRequired = !q_dbus_message_get_no_reply(dmsg);
235
236 QDBusDemarshaller demarshaller(capabilities);
237 demarshaller.message = q_dbus_message_ref(dmsg);
238 if (q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator))
239 while (!demarshaller.atEnd())
240 message << demarshaller.toVariantInternal();
241 return message;
242}
243
244bool QDBusMessagePrivate::isLocal(const QDBusMessage &message)
245{
246 return message.d_ptr->localMessage;
247}
248
249QDBusMessage QDBusMessagePrivate::makeLocal(const QDBusConnectionPrivate &conn,
250 const QDBusMessage &asSent)
251{
252 // simulate the message being sent to the bus and then received back
253 // the only field that the bus sets when delivering the message
254 // (as opposed to the message as we send it), is the sender
255 // so we simply set the sender to our unique name
256
257 // determine if we are carrying any complex types
258 QString computedSignature;
259 for (const QVariant &argument : std::as_const(asSent.d_ptr->arguments)) {
260 QMetaType id = argument.metaType();
261 const char *signature = QDBusMetaType::typeToSignature(id);
262 if ((id.id() != QMetaType::QStringList && id.id() != QMetaType::QByteArray &&
263 qstrlen(signature) != 1) || id == QMetaType::fromType<QDBusVariant>()) {
264 // yes, we are
265 // we must marshall and demarshall again so as to create QDBusArgument
266 // entries for the complex types
267 QDBusError error;
268 DBusMessage *message = toDBusMessage(asSent, conn.connectionCapabilities(), &error);
269 if (!message) {
270 // failed to marshall, so it's a call error
271 return QDBusMessage::createError(error);
272 }
273
274 q_dbus_message_set_sender(message, conn.baseService.toUtf8());
275
276 QDBusMessage retval = fromDBusMessage(message, conn.connectionCapabilities());
277 retval.d_ptr->localMessage = true;
278 q_dbus_message_unref(message);
279 if (retval.d_ptr->service.isEmpty())
280 retval.d_ptr->service = conn.baseService;
281 return retval;
282 } else {
283 computedSignature += QLatin1StringView(signature);
284 }
285 }
286
287 // no complex types seen
288 // optimize by using the variant list itself
289 QDBusMessage retval;
290 QDBusMessagePrivate *d = retval.d_ptr;
291 d->arguments = asSent.d_ptr->arguments;
292 d->path = asSent.d_ptr->path;
293 d->interface = asSent.d_ptr->interface;
294 d->name = asSent.d_ptr->name;
295 d->message = asSent.d_ptr->message;
296 d->type = asSent.d_ptr->type;
297
298 d->service = conn.baseService;
299 d->signature = computedSignature;
300 d->localMessage = true;
301 return retval;
302}
303
304QDBusMessage QDBusMessagePrivate::makeLocalReply(const QDBusConnectionPrivate &conn,
305 const QDBusMessage &callMsg)
306{
307 // simulate the reply (return or error) message being sent to the bus and
308 // then received back.
309 if (callMsg.d_ptr->localReply)
310 return makeLocal(conn, *callMsg.d_ptr->localReply);
311 return QDBusMessage(); // failed
312}
313
314/*!
315 \class QDBusMessage
316 \inmodule QtDBus
317 \since 4.2
318
319 \brief The QDBusMessage class represents one message sent or
320 received over the D-Bus bus.
321
322 This object can represent any of the four different types of
323 messages (MessageType) that can occur on the bus:
324
325 \list
326 \li Method calls
327 \li Method return values
328 \li Signal emissions
329 \li Error codes
330 \endlist
331
332 Objects of this type are created with the static createError(),
333 createMethodCall() and createSignal() functions. Use the
334 QDBusConnection::send() function to send the messages.
335*/
336
337/*!
338 \enum QDBusMessage::MessageType
339 The possible message types:
340
341 \value MethodCallMessage a message representing an outgoing or incoming method call
342 \value SignalMessage a message representing an outgoing or incoming signal emission
343 \value ReplyMessage a message representing the return values of a method call
344 \value ErrorMessage a message representing an error condition in response to a method call
345 \value InvalidMessage an invalid message: this is never set on messages received from D-Bus
346*/
347
348/*!
349 Constructs a new DBus message with the given \a path, \a interface
350 and \a name, representing a signal emission.
351
352 A DBus signal is emitted from one application and is received by
353 all applications that are listening for that signal from that
354 interface.
355
356 The QDBusMessage object that is returned can be sent using the
357 QDBusConnection::send() function.
358*/
359QDBusMessage QDBusMessage::createSignal(const QString &path, const QString &interface,
360 const QString &name)
361{
362 QDBusMessage message;
363 message.d_ptr->type = SignalMessage;
364 message.d_ptr->path = path;
365 message.d_ptr->interface = interface;
366 message.d_ptr->name = name;
367
368 return message;
369}
370
371/*!
372 \since 5.6
373
374 Constructs a new DBus message with the given \a path, \a interface
375 and \a name, representing a signal emission to a specific destination.
376
377 A DBus signal is emitted from one application and is received only by
378 the application owning the destination \a service name.
379
380 The QDBusMessage object that is returned can be sent using the
381 QDBusConnection::send() function.
382*/
383QDBusMessage QDBusMessage::createTargetedSignal(const QString &service, const QString &path,
384 const QString &interface, const QString &name)
385{
386 QDBusMessage message;
387 message.d_ptr->type = SignalMessage;
388 message.d_ptr->service = service;
389 message.d_ptr->path = path;
390 message.d_ptr->interface = interface;
391 message.d_ptr->name = name;
392
393 return message;
394}
395
396/*!
397 Constructs a new DBus message representing a method call.
398 A method call always informs its destination address
399 (\a service, \a path, \a interface and \a method).
400
401 The DBus bus allows calling a method on a given remote object without specifying the
402 destination interface, if the method name is unique. However, if two interfaces on the
403 remote object export the same method name, the result is undefined (one of the two may be
404 called or an error may be returned).
405
406 When using DBus in a peer-to-peer context (i.e., not on a bus), the \a service parameter is
407 optional.
408
409 The QDBusInterface class provides a simpler abstraction to synchronous
410 method calling.
411
412 This function returns a QDBusMessage object that can be sent with
413 QDBusConnection::call().
414*/
415QDBusMessage QDBusMessage::createMethodCall(const QString &service, const QString &path,
416 const QString &interface, const QString &method)
417{
418 QDBusMessage message;
419 message.d_ptr->type = MethodCallMessage;
420 message.d_ptr->service = service;
421 message.d_ptr->path = path;
422 message.d_ptr->interface = interface;
423 message.d_ptr->name = method;
424 message.d_ptr->isReplyRequired = true;
425
426 return message;
427}
428
429/*!
430 Constructs a new DBus message representing an error,
431 with the given \a name and \a msg.
432*/
433QDBusMessage QDBusMessage::createError(const QString &name, const QString &msg)
434{
435 QDBusMessage error;
436 error.d_ptr->type = ErrorMessage;
437 error.d_ptr->name = name;
438 error.d_ptr->message = msg;
439
440 return error;
441}
442
443/*!
444 \fn QDBusMessage QDBusMessage::createError(const QDBusError &error)
445
446 Constructs a new DBus message representing the given \a error.
447*/
448
449/*!
450 \fn QDBusMessage QDBusMessage::createError(QDBusError::ErrorType type, const QString &msg)
451
452 Constructs a new DBus message for the error type \a type using
453 the message \a msg. Returns the DBus message.
454*/
455
456/*!
457 \fn QDBusMessage QDBusMessage::createReply(const QList<QVariant> &arguments) const
458
459 Constructs a new DBus message representing a reply, with the given
460 \a arguments.
461*/
462QDBusMessage QDBusMessage::createReply(const QVariantList &arguments) const
463{
464 QDBusMessage reply;
465 reply.setArguments(arguments);
466 reply.d_ptr->type = ReplyMessage;
467 reply.d_ptr->createResponseLink(d_ptr);
468 return reply;
469}
470
471/*!
472 Constructs a new DBus message representing an error reply message,
473 with the given \a name and \a msg.
474*/
475QDBusMessage QDBusMessage::createErrorReply(const QString &name, const QString &msg) const
476{
477 QDBusMessage reply = QDBusMessage::createError(name, msg);
478 reply.d_ptr->createResponseLink(d_ptr);
479 return reply;
480}
481
482/*!
483 Constructs a new DBus message representing a reply, with the
484 given \a argument.
485*/
486QDBusMessage QDBusMessage::createReply(const QVariant &argument) const
487{
488 return createReply(QList{argument});
489}
490
491/*!
492 \fn QDBusMessage QDBusMessage::createErrorReply(const QDBusError &error) const
493
494 Constructs a new DBus message representing an error reply message,
495 from the given \a error object.
496*/
497
498/*!
499 \fn QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType type, const QString &msg) const
500
501 Constructs a new DBus reply message for the error type \a type using
502 the message \a msg. Returns the DBus message.
503*/
504QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const
505{
506 QDBusMessage msg = createErrorReply(QDBusError::errorString(atype), amsg);
507 msg.d_ptr->parametersValidated = true;
508 return msg;
509}
510
511
512/*!
513 Constructs an empty, invalid QDBusMessage object.
514
515 \sa createError(), createMethodCall(), createSignal()
516*/
517QDBusMessage::QDBusMessage()
518{
519 d_ptr = new QDBusMessagePrivate;
520}
521
522/*!
523 Constructs a copy of the object given by \a other.
524
525 Note: QDBusMessage objects are shared. Modifications made to the
526 copy will affect the original one as well. See setDelayedReply()
527 for more information.
528*/
529QDBusMessage::QDBusMessage(const QDBusMessage &other)
530{
531 d_ptr = other.d_ptr;
532 d_ptr->ref.ref();
533}
534
535/*!
536 Disposes of the object and frees any resources that were being held.
537*/
538QDBusMessage::~QDBusMessage()
539{
540 if (!d_ptr->ref.deref())
541 delete d_ptr;
542}
543
544/*!
545 Copies the contents of the object given by \a other.
546
547 Note: QDBusMessage objects are shared. Modifications made to the
548 copy will affect the original one as well. See setDelayedReply()
549 for more information.
550*/
551QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
552{
553 qAtomicAssign(d_ptr, other.d_ptr);
554 return *this;
555}
556
557/*!
558 Returns the name of the service or the bus address of the remote method call.
559*/
560QString QDBusMessage::service() const
561{
562 if (d_ptr->type == ErrorMessage || d_ptr->type == ReplyMessage)
563 return QString(); // d_ptr->service holds the destination
564 return d_ptr->service;
565}
566
567/*!
568 Returns the path of the object that this message is being sent to (in the case of a
569 method call) or being received from (for a signal).
570*/
571QString QDBusMessage::path() const
572{
573 return d_ptr->path;
574}
575
576/*!
577 Returns the interface of the method being called (in the case of a method call) or of
578 the signal being received from.
579*/
580QString QDBusMessage::interface() const
581{
582 return d_ptr->interface;
583}
584
585/*!
586 Returns the name of the signal that was emitted or the name of the method that was called.
587*/
588QString QDBusMessage::member() const
589{
590 if (d_ptr->type != ErrorMessage)
591 return d_ptr->name;
592 return QString();
593}
594
595/*!
596 Returns the name of the error that was received.
597*/
598QString QDBusMessage::errorName() const
599{
600 if (d_ptr->type == ErrorMessage)
601 return d_ptr->name;
602 return QString();
603}
604
605/*!
606 Returns the signature of the signal that was received or for the output arguments
607 of a method call.
608*/
609QString QDBusMessage::signature() const
610{
611 return d_ptr->signature;
612}
613
614/*!
615 Returns the flag that indicates if this message should see a reply
616 or not. This is only meaningful for \l {MethodCallMessage}{method
617 call messages}: any other kind of message cannot have replies and
618 this function will always return false for them.
619*/
620bool QDBusMessage::isReplyRequired() const
621{
622 // Only method calls can have replies
623 if (d_ptr->type != QDBusMessage::MethodCallMessage)
624 return false;
625
626 if (d_ptr->localMessage) // if it's a local message, reply is required
627 return true;
628 return d_ptr->isReplyRequired;
629}
630
631/*!
632 Sets whether the message will be replied later (if \a enable is
633 true) or if an automatic reply should be generated by Qt D-Bus
634 (if \a enable is false).
635
636 In D-Bus, all method calls must generate a reply to the caller, unless the
637 caller explicitly indicates otherwise (see isReplyRequired()). QtDBus
638 automatically generates such replies for any slots being called, but it
639 also allows slots to indicate whether they will take responsibility
640 of sending the reply at a later time, after the function has finished
641 processing.
642
643 \sa {Delayed Replies}
644*/
645void QDBusMessage::setDelayedReply(bool enable) const
646{
647 d_ptr->delayedReply = enable;
648}
649
650/*!
651 Returns the delayed reply flag, as set by setDelayedReply(). By default, this
652 flag is false, which means Qt D-Bus will generate automatic replies
653 when necessary.
654*/
655bool QDBusMessage::isDelayedReply() const
656{
657 return d_ptr->delayedReply;
658}
659
660/*!
661 Sets the auto start flag to \a enable. This flag only makes sense
662 for method call messages, where it tells the D-Bus server to
663 either auto start the service responsible for the service name, or
664 not to auto start it.
665
666 By default this flag is true, i.e. a service is autostarted.
667 This means:
668
669 When the service that this method call is sent to is already
670 running, the method call is sent to it. If the service is not
671 running yet, the D-Bus daemon is requested to autostart the
672 service that is assigned to this service name. This is
673 handled by .service files that are placed in a directory known
674 to the D-Bus server. These files then each contain a service
675 name and the path to a program that should be executed when
676 this service name is requested.
677
678 \since 4.7
679*/
680void QDBusMessage::setAutoStartService(bool enable)
681{
682 d_ptr->autoStartService = enable;
683}
684
685/*!
686 Returns the auto start flag, as set by setAutoStartService(). By default, this
687 flag is true, which means Qt D-Bus will auto start a service, if it is
688 not running already.
689
690 \sa setAutoStartService()
691
692 \since 4.7
693*/
694bool QDBusMessage::autoStartService() const
695{
696 return d_ptr->autoStartService;
697}
698
699/*!
700 Enables or disables the \c ALLOW_INTERACTIVE_AUTHORIZATION flag
701 in a message.
702
703 This flag only makes sense for method call messages
704 (\l QDBusMessage::MethodCallMessage). If \a enable
705 is set to \c true, the flag indicates to the callee that the
706 caller of the method is prepared to wait for interactive authorization
707 to take place (for instance via Polkit) before the actual method
708 is processed.
709
710 If \a enable is set to \c false, the flag is not
711 set, meaning that the other end is expected to make any authorization
712 decisions non-interactively and promptly. This is the default.
713
714 The \c org.freedesktop.DBus.Error.InteractiveAuthorizationRequired
715 error indicates that authorization failed, but could have succeeded
716 if this flag had been set.
717
718 \sa isInteractiveAuthorizationAllowed(),
719 QDBusAbstractInterface::setInteractiveAuthorizationAllowed()
720
721 \since 5.12
722*/
723void QDBusMessage::setInteractiveAuthorizationAllowed(bool enable)
724{
725 d_ptr->interactiveAuthorizationAllowed = enable;
726}
727
728/*!
729 Returns whether the message has the
730 \c ALLOW_INTERACTIVE_AUTHORIZATION flag set.
731
732 \sa setInteractiveAuthorizationAllowed(),
733 QDBusAbstractInterface::isInteractiveAuthorizationAllowed()
734
735 \since 5.12
736*/
737bool QDBusMessage::isInteractiveAuthorizationAllowed() const
738{
739 return d_ptr->interactiveAuthorizationAllowed;
740}
741
742/*!
743 Sets the arguments that are going to be sent over D-Bus to \a arguments. Those
744 will be the arguments to a method call or the parameters in the signal.
745
746 Note that QVariantMap with invalid QVariant as value is not allowed
747 in \a arguments.
748
749 \sa arguments()
750*/
751void QDBusMessage::setArguments(const QList<QVariant> &arguments)
752{
753 d_ptr->arguments = arguments;
754}
755
756/*!
757 Returns the list of arguments that are going to be sent or were received from
758 D-Bus.
759*/
760QList<QVariant> QDBusMessage::arguments() const
761{
762 return d_ptr->arguments;
763}
764
765/*!
766 Appends the argument \a arg to the list of arguments to be sent over D-Bus in
767 a method call or signal emission.
768*/
769
770QDBusMessage &QDBusMessage::operator<<(const QVariant &arg)
771{
772 d_ptr->arguments.append(arg);
773 return *this;
774}
775
776QDBusMessage::QDBusMessage(QDBusMessagePrivate &dd)
777 : d_ptr(&dd)
778{
779 d_ptr->ref.ref();
780}
781
782/*!
783 Returns the message type.
784*/
785QDBusMessage::MessageType QDBusMessage::type() const
786{
787 switch (d_ptr->type) {
789 return MethodCallMessage;
791 return ReplyMessage;
793 return ErrorMessage;
795 return SignalMessage;
796 default:
797 break;
798 }
799 return InvalidMessage;
800}
801
802#ifndef QT_NO_DEBUG_STREAM
803static QDebug operator<<(QDebug dbg, QDBusMessage::MessageType t)
804{
805 switch (t)
806 {
807 case QDBusMessage::MethodCallMessage:
808 return dbg << "MethodCall";
809 case QDBusMessage::ReplyMessage:
810 return dbg << "MethodReturn";
811 case QDBusMessage::SignalMessage:
812 return dbg << "Signal";
813 case QDBusMessage::ErrorMessage:
814 return dbg << "Error";
815 default:
816 return dbg << "Invalid";
817 }
818}
819
820static void debugVariantList(QDebug dbg, const QVariantList &list)
821{
822 bool first = true;
823 for (const QVariant &elem : list) {
824 if (!first)
825 dbg.nospace() << ", ";
826 dbg.nospace() << qPrintable(QDBusUtil::argumentToString(elem));
827 first = false;
828 }
829}
830
831QDebug operator<<(QDebug dbg, const QDBusMessage &msg)
832{
833 QDebugStateSaver saver(dbg);
834 dbg.nospace() << "QDBusMessage(type=" << msg.type()
835 << ", service=" << msg.service();
836 if (msg.type() == QDBusMessage::MethodCallMessage ||
837 msg.type() == QDBusMessage::SignalMessage)
838 dbg.nospace() << ", path=" << msg.path()
839 << ", interface=" << msg.interface()
840 << ", member=" << msg.member();
841 if (msg.type() == QDBusMessage::ErrorMessage)
842 dbg.nospace() << ", error name=" << msg.errorName()
843 << ", error message=" << msg.errorMessage();
844 dbg.nospace() << ", signature=" << msg.signature()
845 << ", contents=(";
846 debugVariantList(dbg, msg.arguments());
847 dbg.nospace() << ") )";
848 return dbg;
849}
850#endif
851
852/*!
853 \fn void QDBusMessage::swap(QDBusMessage &other)
854 \memberswap{message}
855*/
856
857QT_END_NAMESPACE
858
859#endif // QT_NO_DBUS
constexpr QAtomicInt(int value=0) noexcept
Constructs a QAtomicInt with the given value.
Definition qatomic.h:117
QDBusArgument::ElementType currentType()
void createResponseLink(const QDBusMessagePrivate *call)
QDBusMessage * localReply
static QDBusMessage makeLocalReply(const QDBusConnectionPrivate &conn, const QDBusMessage &asSent)
static bool isLocal(const QDBusMessage &msg)
static QDBusMessage makeLocal(const QDBusConnectionPrivate &conn, const QDBusMessage &asSent)
\inmodule QtDBus
#define DBUS_MESSAGE_TYPE_METHOD_CALL
#define DBUS_MESSAGE_TYPE_ERROR
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
#define DBUS_MESSAGE_TYPE_SIGNAL
#define DBUS_MESSAGE_TYPE_INVALID
\inmodule QtDBus
Definition qdbusutil_p.h:32
@ EmptyNotAllowed
Definition qdbusutil_p.h:59
Combined button and popup list for selecting options.
bool qdbus_loadLibDBus()
static void debugVariantList(QDebug dbg, const QVariantList &list)
QDebug operator<<(QDebug dbg, const QDBusMessage &msg)
static QDebug operator<<(QDebug dbg, QDBusMessage::MessageType t)
static const char * data(const QByteArray &arr)
#define qPrintable(string)
Definition qstring.h:1666