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