summaryrefslogtreecommitdiffstats
path: root/src/dbus/qdbusmessage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dbus/qdbusmessage.cpp')
-rw-r--r--src/dbus/qdbusmessage.cpp108
1 files changed, 61 insertions, 47 deletions
diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp
index 6372fe0496..6ef762f225 100644
--- a/src/dbus/qdbusmessage.cpp
+++ b/src/dbus/qdbusmessage.cpp
@@ -36,22 +36,37 @@ static inline const char *data(const QByteArray &arr)
}
QDBusMessagePrivate::QDBusMessagePrivate()
- : msg(nullptr), reply(nullptr), localReply(nullptr), ref(1), type(QDBusMessage::InvalidMessage),
- delayedReply(false), localMessage(false),
- parametersValidated(false), autoStartService(true),
- interactiveAuthorizationAllowed(false)
+ : localReply(nullptr), ref(1), type(QDBusMessage::InvalidMessage),
+ delayedReply(false), parametersValidated(false),
+ localMessage(false), autoStartService(true),
+ interactiveAuthorizationAllowed(false), isReplyRequired(false)
{
}
QDBusMessagePrivate::~QDBusMessagePrivate()
{
- if (msg)
- q_dbus_message_unref(msg);
- if (reply)
- q_dbus_message_unref(reply);
delete localReply;
}
+void QDBusMessagePrivate::createResponseLink(const QDBusMessagePrivate *call)
+{
+ if (Q_UNLIKELY(call->type != QDBusMessage::MethodCallMessage)) {
+ qWarning("QDBusMessage: replying to a message that isn't a method call");
+ return;
+ }
+
+ if (call->localMessage) {
+ localMessage = true;
+ call->localReply = new QDBusMessage(*this); // keep an internal copy
+ } else {
+ serial = call->serial;
+ service = call->service;
+ }
+
+ // the reply must have a serial or be a local-loop optimization
+ Q_ASSERT(serial || localMessage);
+}
+
/*!
\since 4.3
Returns the human-readable message associated with the error that was received.
@@ -113,8 +128,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB
case QDBusMessage::ReplyMessage:
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
if (!d_ptr->localMessage) {
- q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply));
- q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply));
+ q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8()));
+ q_dbus_message_set_reply_serial(msg, d_ptr->serial);
}
break;
case QDBusMessage::ErrorMessage:
@@ -126,8 +141,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8());
if (!d_ptr->localMessage) {
- q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply));
- q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply));
+ q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8()));
+ q_dbus_message_set_reply_serial(msg, d_ptr->serial);
}
break;
case QDBusMessage::SignalMessage:
@@ -204,6 +219,7 @@ QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnec
return message;
message.d_ptr->type = QDBusMessage::MessageType(q_dbus_message_get_type(dmsg));
+ message.d_ptr->serial = q_dbus_message_get_serial(dmsg);
message.d_ptr->path = QString::fromUtf8(q_dbus_message_get_path(dmsg));
message.d_ptr->interface = QString::fromUtf8(q_dbus_message_get_interface(dmsg));
message.d_ptr->name = message.d_ptr->type == DBUS_MESSAGE_TYPE_ERROR ?
@@ -212,7 +228,7 @@ QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnec
message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
message.d_ptr->interactiveAuthorizationAllowed = q_dbus_message_get_allow_interactive_authorization(dmsg);
- message.d_ptr->msg = q_dbus_message_ref(dmsg);
+ message.d_ptr->isReplyRequired = !q_dbus_message_get_no_reply(dmsg);
QDBusDemarshaller demarshaller(capabilities);
demarshaller.message = q_dbus_message_ref(dmsg);
@@ -402,6 +418,7 @@ QDBusMessage QDBusMessage::createMethodCall(const QString &service, const QStrin
message.d_ptr->path = path;
message.d_ptr->interface = interface;
message.d_ptr->name = method;
+ message.d_ptr->isReplyRequired = true;
return message;
}
@@ -444,15 +461,7 @@ QDBusMessage QDBusMessage::createReply(const QVariantList &arguments) const
QDBusMessage reply;
reply.setArguments(arguments);
reply.d_ptr->type = ReplyMessage;
- if (d_ptr->msg)
- reply.d_ptr->reply = q_dbus_message_ref(d_ptr->msg);
- if (d_ptr->localMessage) {
- reply.d_ptr->localMessage = true;
- d_ptr->localReply = new QDBusMessage(reply); // keep an internal copy
- }
-
- // the reply must have a msg or be a local-loop optimization
- Q_ASSERT(reply.d_ptr->reply || reply.d_ptr->localMessage);
+ reply.d_ptr->createResponseLink(d_ptr);
return reply;
}
@@ -463,15 +472,7 @@ QDBusMessage QDBusMessage::createReply(const QVariantList &arguments) const
QDBusMessage QDBusMessage::createErrorReply(const QString &name, const QString &msg) const
{
QDBusMessage reply = QDBusMessage::createError(name, msg);
- if (d_ptr->msg)
- reply.d_ptr->reply = q_dbus_message_ref(d_ptr->msg);
- if (d_ptr->localMessage) {
- reply.d_ptr->localMessage = true;
- d_ptr->localReply = new QDBusMessage(reply); // keep an internal copy
- }
-
- // the reply must have a msg or be a local-loop optimization
- Q_ASSERT(reply.d_ptr->reply || reply.d_ptr->localMessage);
+ reply.d_ptr->createResponseLink(d_ptr);
return reply;
}
@@ -555,6 +556,8 @@ QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
*/
QString QDBusMessage::service() const
{
+ if (d_ptr->type == ErrorMessage || d_ptr->type == ReplyMessage)
+ return QString(); // d_ptr->service holds the destination
return d_ptr->service;
}
@@ -617,9 +620,9 @@ bool QDBusMessage::isReplyRequired() const
if (d_ptr->type != QDBusMessage::MethodCallMessage)
return false;
- if (!d_ptr->msg)
- return d_ptr->localMessage; // if it's a local message, reply is required
- return !q_dbus_message_get_no_reply(d_ptr->msg);
+ if (d_ptr->localMessage) // if it's a local message, reply is required
+ return true;
+ return d_ptr->isReplyRequired;
}
/*!
@@ -691,20 +694,26 @@ bool QDBusMessage::autoStartService() const
}
/*!
- Sets the interactive authorization flag to \a enable.
- This flag only makes sense for method call messages, where it
- tells the D-Bus server that the caller of the method is prepared
- to wait for interactive authorization to take place (for instance
- via Polkit) before the actual method is processed.
+ Enables or disables the \c ALLOW_INTERACTIVE_AUTHORIZATION flag
+ in a message.
+
+ This flag only makes sense for method call messages
+ (\l QDBusMessage::MethodCallMessage). If \a enable
+ is set to \c true, the flag indicates to the callee that the
+ caller of the method is prepared to wait for interactive authorization
+ to take place (for instance via Polkit) before the actual method
+ is processed.
- By default this flag is false and the other end is expected to
- make any authorization decisions non-interactively and promptly.
+ If \a enable is set to \c false, the flag is not
+ set, meaning that the other end is expected to make any authorization
+ decisions non-interactively and promptly. This is the default.
The \c org.freedesktop.DBus.Error.InteractiveAuthorizationRequired
error indicates that authorization failed, but could have succeeded
if this flag had been set.
- \sa isInteractiveAuthorizationAllowed()
+ \sa isInteractiveAuthorizationAllowed(),
+ QDBusAbstractInterface::setInteractiveAuthorizationAllowed()
\since 5.12
*/
@@ -714,12 +723,11 @@ void QDBusMessage::setInteractiveAuthorizationAllowed(bool enable)
}
/*!
- Returns the interactive authorization allowed flag, as set by
- setInteractiveAuthorizationAllowed(). By default this flag
- is false and the other end is expected to make any authorization
- decisions non-interactively and promptly.
+ Returns whether the message has the
+ \c ALLOW_INTERACTIVE_AUTHORIZATION flag set.
- \sa setInteractiveAuthorizationAllowed()
+ \sa setInteractiveAuthorizationAllowed(),
+ QDBusAbstractInterface::isInteractiveAuthorizationAllowed()
\since 5.12
*/
@@ -759,6 +767,12 @@ QDBusMessage &QDBusMessage::operator<<(const QVariant &arg)
return *this;
}
+QDBusMessage::QDBusMessage(QDBusMessagePrivate &dd)
+ : d_ptr(&dd)
+{
+ d_ptr->ref.ref();
+}
+
/*!
Returns the message type.
*/