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