mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-14 14:27:14 +01:00
GDBusConnection.call(): add 'reply_type' argument
This allows the caller to specify the reply type that they are expecting for this call. If the reply comes back with the wrong type, GDBus will generate an appropriate error internally. - add a GVariantType * argument to g_dbus_connection_call() and _call_sync(). - move the internal API for computing message types from introspection data to be based on GVariantType instead of strings. Update users of this code. - have GDBusProxy pass this calculated GVariantType into g_dbus_connection_call(). Remove the checks done in GDBusProxy. - Update other users of the code (test cases, gdbus-tool, GSettings tool, etc). In some cases, remove redundant checks; in some other cases, we are fixing bugs because no checking was done where it should have been. Closes bug #619391.
This commit is contained in:
parent
100df5287d
commit
3160bcad6a
@ -150,6 +150,7 @@ print_methods (GDBusConnection *c,
|
|||||||
"org.freedesktop.DBus.Introspectable",
|
"org.freedesktop.DBus.Introspectable",
|
||||||
"Introspect",
|
"Introspect",
|
||||||
NULL,
|
NULL,
|
||||||
|
G_VARIANT_TYPE ("(s)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
3000, /* 3 secs */
|
3000, /* 3 secs */
|
||||||
NULL,
|
NULL,
|
||||||
@ -160,13 +161,6 @@ print_methods (GDBusConnection *c,
|
|||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(s)")))
|
|
||||||
{
|
|
||||||
g_printerr (_("Error: Result is type `%s', expected `(s)'\n"),
|
|
||||||
g_variant_get_type_string (result));
|
|
||||||
g_variant_unref (result);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
g_variant_get (result, "(&s)", &xml_data);
|
g_variant_get (result, "(&s)", &xml_data);
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
@ -212,6 +206,7 @@ print_paths (GDBusConnection *c,
|
|||||||
"org.freedesktop.DBus.Introspectable",
|
"org.freedesktop.DBus.Introspectable",
|
||||||
"Introspect",
|
"Introspect",
|
||||||
NULL,
|
NULL,
|
||||||
|
G_VARIANT_TYPE ("(s)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
3000, /* 3 secs */
|
3000, /* 3 secs */
|
||||||
NULL,
|
NULL,
|
||||||
@ -222,13 +217,6 @@ print_paths (GDBusConnection *c,
|
|||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(s)")))
|
|
||||||
{
|
|
||||||
g_printerr (_("Error: Result is type `%s', expected `(s)'\n"),
|
|
||||||
g_variant_get_type_string (result));
|
|
||||||
g_variant_unref (result);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
g_variant_get (result, "(&s)", &xml_data);
|
g_variant_get (result, "(&s)", &xml_data);
|
||||||
|
|
||||||
//g_printerr ("xml=`%s'", xml_data);
|
//g_printerr ("xml=`%s'", xml_data);
|
||||||
@ -290,6 +278,7 @@ print_names (GDBusConnection *c,
|
|||||||
"org.freedesktop.DBus",
|
"org.freedesktop.DBus",
|
||||||
"ListNames",
|
"ListNames",
|
||||||
NULL,
|
NULL,
|
||||||
|
G_VARIANT_TYPE ("(as)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
3000, /* 3 secs */
|
3000, /* 3 secs */
|
||||||
NULL,
|
NULL,
|
||||||
@ -300,12 +289,6 @@ print_names (GDBusConnection *c,
|
|||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(as)")))
|
|
||||||
{
|
|
||||||
g_printerr (_("Error: Result is type `%s', expected `(as)'\n"), g_variant_get_type_string (result));
|
|
||||||
g_variant_unref (result);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
g_variant_get (result, "(as)", &iter);
|
g_variant_get (result, "(as)", &iter);
|
||||||
while (g_variant_iter_loop (iter, "s", &str))
|
while (g_variant_iter_loop (iter, "s", &str))
|
||||||
g_hash_table_insert (name_set, g_strdup (str), NULL);
|
g_hash_table_insert (name_set, g_strdup (str), NULL);
|
||||||
@ -319,6 +302,7 @@ print_names (GDBusConnection *c,
|
|||||||
"org.freedesktop.DBus",
|
"org.freedesktop.DBus",
|
||||||
"ListActivatableNames",
|
"ListActivatableNames",
|
||||||
NULL,
|
NULL,
|
||||||
|
G_VARIANT_TYPE ("(as)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
3000, /* 3 secs */
|
3000, /* 3 secs */
|
||||||
NULL,
|
NULL,
|
||||||
@ -329,12 +313,6 @@ print_names (GDBusConnection *c,
|
|||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(as)")))
|
|
||||||
{
|
|
||||||
g_printerr (_("Error: Result is type `%s', expected `(as)'\n"), g_variant_get_type_string (result));
|
|
||||||
g_variant_unref (result);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
g_variant_get (result, "(as)", &iter);
|
g_variant_get (result, "(as)", &iter);
|
||||||
while (g_variant_iter_loop (iter, "s", &str))
|
while (g_variant_iter_loop (iter, "s", &str))
|
||||||
g_hash_table_insert (name_set, g_strdup (str), NULL);
|
g_hash_table_insert (name_set, g_strdup (str), NULL);
|
||||||
@ -461,6 +439,7 @@ call_helper_get_method_in_signature (GDBusConnection *c,
|
|||||||
"org.freedesktop.DBus.Introspectable",
|
"org.freedesktop.DBus.Introspectable",
|
||||||
"Introspect",
|
"Introspect",
|
||||||
NULL,
|
NULL,
|
||||||
|
G_VARIANT_TYPE ("(s)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
3000, /* 3 secs */
|
3000, /* 3 secs */
|
||||||
NULL,
|
NULL,
|
||||||
@ -468,14 +447,6 @@ call_helper_get_method_in_signature (GDBusConnection *c,
|
|||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(s)")))
|
|
||||||
{
|
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
||||||
_("Error: Result is type `%s', expected `(s)'\n"),
|
|
||||||
g_variant_get_type_string (result));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_variant_get (result, "(&s)", &xml_data);
|
g_variant_get (result, "(&s)", &xml_data);
|
||||||
node_info = g_dbus_node_info_new_for_xml (xml_data, error);
|
node_info = g_dbus_node_info_new_for_xml (xml_data, error);
|
||||||
if (node_info == NULL)
|
if (node_info == NULL)
|
||||||
@ -833,6 +804,7 @@ handle_call (gint *argc,
|
|||||||
interface_name,
|
interface_name,
|
||||||
method_name,
|
method_name,
|
||||||
parameters,
|
parameters,
|
||||||
|
NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
@ -1056,6 +1028,7 @@ dump_interface (GDBusConnection *c,
|
|||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"GetAll",
|
"GetAll",
|
||||||
g_variant_new ("(s)", o->name),
|
g_variant_new ("(s)", o->name),
|
||||||
|
NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
3000,
|
3000,
|
||||||
NULL,
|
NULL,
|
||||||
@ -1094,6 +1067,7 @@ dump_interface (GDBusConnection *c,
|
|||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"Get",
|
"Get",
|
||||||
g_variant_new ("(ss)", o->name, o->properties[n]->name),
|
g_variant_new ("(ss)", o->name, o->properties[n]->name),
|
||||||
|
G_VARIANT_TYPE ("(v)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
3000,
|
3000,
|
||||||
NULL,
|
NULL,
|
||||||
@ -1338,6 +1312,7 @@ handle_introspect (gint *argc,
|
|||||||
"org.freedesktop.DBus.Introspectable",
|
"org.freedesktop.DBus.Introspectable",
|
||||||
"Introspect",
|
"Introspect",
|
||||||
NULL,
|
NULL,
|
||||||
|
G_VARIANT_TYPE ("(s)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
3000, /* 3 sec */
|
3000, /* 3 sec */
|
||||||
NULL,
|
NULL,
|
||||||
@ -1348,12 +1323,6 @@ handle_introspect (gint *argc,
|
|||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(s)")))
|
|
||||||
{
|
|
||||||
g_printerr (_("Error: Result is type `%s', expected `(s)'\n"),
|
|
||||||
g_variant_get_type_string (result));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
g_variant_get (result, "(&s)", &xml_data);
|
g_variant_get (result, "(&s)", &xml_data);
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
|
@ -1845,6 +1845,7 @@ initable_init (GInitable *initable,
|
|||||||
"org.freedesktop.DBus", /* interface */
|
"org.freedesktop.DBus", /* interface */
|
||||||
"Hello",
|
"Hello",
|
||||||
NULL, /* parameters */
|
NULL, /* parameters */
|
||||||
|
G_VARIANT_TYPE ("(s)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL, /* TODO: cancellable */
|
NULL, /* TODO: cancellable */
|
||||||
@ -3730,7 +3731,7 @@ validate_and_maybe_schedule_method_call (GDBusConnection *connection,
|
|||||||
GVariant *parameters;
|
GVariant *parameters;
|
||||||
GSource *idle_source;
|
GSource *idle_source;
|
||||||
gboolean handled;
|
gboolean handled;
|
||||||
gchar *in_signature;
|
GVariantType *in_type;
|
||||||
|
|
||||||
handled = FALSE;
|
handled = FALSE;
|
||||||
|
|
||||||
@ -3752,27 +3753,6 @@ validate_and_maybe_schedule_method_call (GDBusConnection *connection,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the incoming args are of the right type - if they are not, return
|
|
||||||
* the org.freedesktop.DBus.Error.InvalidArgs error to the caller
|
|
||||||
*
|
|
||||||
* TODO: might also be worth caching the combined signature.
|
|
||||||
*/
|
|
||||||
in_signature = _g_dbus_compute_complete_signature (method_info->in_args, FALSE);
|
|
||||||
if (g_strcmp0 (g_dbus_message_get_signature (message), in_signature) != 0)
|
|
||||||
{
|
|
||||||
reply = g_dbus_message_new_method_error (message,
|
|
||||||
"org.freedesktop.DBus.Error.InvalidArgs",
|
|
||||||
_("Signature of message, `%s', does not match expected signature `%s'"),
|
|
||||||
g_dbus_message_get_signature (message),
|
|
||||||
in_signature);
|
|
||||||
g_dbus_connection_send_message_unlocked (connection, reply, NULL, NULL);
|
|
||||||
g_object_unref (reply);
|
|
||||||
g_free (in_signature);
|
|
||||||
handled = TRUE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
g_free (in_signature);
|
|
||||||
|
|
||||||
parameters = g_dbus_message_get_body (message);
|
parameters = g_dbus_message_get_body (message);
|
||||||
if (parameters == NULL)
|
if (parameters == NULL)
|
||||||
{
|
{
|
||||||
@ -3784,6 +3764,31 @@ validate_and_maybe_schedule_method_call (GDBusConnection *connection,
|
|||||||
g_variant_ref (parameters);
|
g_variant_ref (parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check that the incoming args are of the right type - if they are not, return
|
||||||
|
* the org.freedesktop.DBus.Error.InvalidArgs error to the caller
|
||||||
|
*/
|
||||||
|
in_type = _g_dbus_compute_complete_signature (method_info->in_args);
|
||||||
|
if (!g_variant_is_of_type (parameters, in_type))
|
||||||
|
{
|
||||||
|
gchar *type_string;
|
||||||
|
|
||||||
|
type_string = g_variant_type_dup_string (in_type);
|
||||||
|
|
||||||
|
reply = g_dbus_message_new_method_error (message,
|
||||||
|
"org.freedesktop.DBus.Error.InvalidArgs",
|
||||||
|
_("Type of message, `%s', does not match expected type `%s'"),
|
||||||
|
g_variant_get_type_string (parameters),
|
||||||
|
type_string);
|
||||||
|
g_dbus_connection_send_message_unlocked (connection, reply, NULL, NULL);
|
||||||
|
g_variant_type_free (in_type);
|
||||||
|
g_variant_unref (parameters);
|
||||||
|
g_object_unref (reply);
|
||||||
|
g_free (type_string);
|
||||||
|
handled = TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
g_variant_type_free (in_type);
|
||||||
|
|
||||||
/* schedule the call in idle */
|
/* schedule the call in idle */
|
||||||
invocation = g_dbus_method_invocation_new (g_dbus_message_get_sender (message),
|
invocation = g_dbus_method_invocation_new (g_dbus_message_get_sender (message),
|
||||||
g_dbus_message_get_path (message),
|
g_dbus_message_get_path (message),
|
||||||
@ -4131,6 +4136,105 @@ add_call_flags (GDBusMessage *message,
|
|||||||
g_dbus_message_set_flags (message, G_DBUS_MESSAGE_FLAGS_NO_AUTO_START);
|
g_dbus_message_set_flags (message, G_DBUS_MESSAGE_FLAGS_NO_AUTO_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
decode_method_reply (GDBusMessage *reply,
|
||||||
|
const gchar *method_name,
|
||||||
|
const GVariantType *reply_type,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GVariant *result;
|
||||||
|
|
||||||
|
result = NULL;
|
||||||
|
switch (g_dbus_message_get_message_type (reply))
|
||||||
|
{
|
||||||
|
case G_DBUS_MESSAGE_TYPE_METHOD_RETURN:
|
||||||
|
result = g_dbus_message_get_body (reply);
|
||||||
|
if (result == NULL)
|
||||||
|
{
|
||||||
|
result = g_variant_new ("()");
|
||||||
|
g_variant_ref_sink (result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_variant_ref (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_variant_is_of_type (result, reply_type))
|
||||||
|
{
|
||||||
|
gchar *type_string = g_variant_type_dup_string (reply_type);
|
||||||
|
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
_("Method `%s' returned type `%s', but expected `%s'"),
|
||||||
|
method_name, g_variant_get_type_string (result), type_string);
|
||||||
|
|
||||||
|
g_variant_unref (result);
|
||||||
|
g_free (type_string);
|
||||||
|
result = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case G_DBUS_MESSAGE_TYPE_ERROR:
|
||||||
|
g_dbus_message_to_gerror (reply, error);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GSimpleAsyncResult *simple;
|
||||||
|
GVariantType *reply_type;
|
||||||
|
gchar *method_name; /* for error message */
|
||||||
|
} CallState;
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_dbus_connection_call_done (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDBusConnection *connection = G_DBUS_CONNECTION (source);
|
||||||
|
CallState *state = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
GDBusMessage *reply;
|
||||||
|
GVariant *value;
|
||||||
|
|
||||||
|
reply = g_dbus_connection_send_message_with_reply_finish (connection,
|
||||||
|
result, &error);
|
||||||
|
|
||||||
|
if (reply != NULL)
|
||||||
|
{
|
||||||
|
value = decode_method_reply (reply, state->method_name,
|
||||||
|
state->reply_type, &error);
|
||||||
|
g_object_unref (reply);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value = NULL;
|
||||||
|
|
||||||
|
if (value == NULL)
|
||||||
|
{
|
||||||
|
g_simple_async_result_set_from_error (state->simple, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_simple_async_result_set_op_res_gpointer (state->simple, value,
|
||||||
|
(GDestroyNotify) g_variant_unref);
|
||||||
|
|
||||||
|
g_simple_async_result_complete (state->simple);
|
||||||
|
g_variant_type_free (state->reply_type);
|
||||||
|
g_object_unref (state->simple);
|
||||||
|
g_free (state->method_name);
|
||||||
|
|
||||||
|
g_slice_free (CallState, state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_dbus_connection_call:
|
* g_dbus_connection_call:
|
||||||
* @connection: A #GDBusConnection.
|
* @connection: A #GDBusConnection.
|
||||||
@ -4139,6 +4243,7 @@ add_call_flags (GDBusMessage *message,
|
|||||||
* @interface_name: D-Bus interface to invoke method on.
|
* @interface_name: D-Bus interface to invoke method on.
|
||||||
* @method_name: The name of the method to invoke.
|
* @method_name: The name of the method to invoke.
|
||||||
* @parameters: A #GVariant tuple with parameters for the method or %NULL if not passing parameters.
|
* @parameters: A #GVariant tuple with parameters for the method or %NULL if not passing parameters.
|
||||||
|
* @reply_type: The expected type of the reply, or %NULL.
|
||||||
* @flags: Flags from the #GDBusCallFlags enumeration.
|
* @flags: Flags from the #GDBusCallFlags enumeration.
|
||||||
* @timeout_msec: The timeout in milliseconds or -1 to use the default timeout.
|
* @timeout_msec: The timeout in milliseconds or -1 to use the default timeout.
|
||||||
* @cancellable: A #GCancellable or %NULL.
|
* @cancellable: A #GCancellable or %NULL.
|
||||||
@ -4156,6 +4261,10 @@ add_call_flags (GDBusMessage *message,
|
|||||||
* not compatible with the D-Bus protocol, the operation fails with
|
* not compatible with the D-Bus protocol, the operation fails with
|
||||||
* %G_IO_ERROR_INVALID_ARGUMENT.
|
* %G_IO_ERROR_INVALID_ARGUMENT.
|
||||||
*
|
*
|
||||||
|
* If @reply_type is non-%NULL then the reply will be checked for having this type and an
|
||||||
|
* error will be raised if it does not match. Said another way, if you give a @reply_type
|
||||||
|
* then any non-%NULL return value will be of this type.
|
||||||
|
*
|
||||||
* If the @parameters #GVariant is floating, it is consumed. This allows
|
* If the @parameters #GVariant is floating, it is consumed. This allows
|
||||||
* convenient 'inline' use of g_variant_new(), e.g.:
|
* convenient 'inline' use of g_variant_new(), e.g.:
|
||||||
* |[
|
* |[
|
||||||
@ -4167,6 +4276,7 @@ add_call_flags (GDBusMessage *message,
|
|||||||
* g_variant_new ("(ss)",
|
* g_variant_new ("(ss)",
|
||||||
* "Thing One",
|
* "Thing One",
|
||||||
* "Thing Two"),
|
* "Thing Two"),
|
||||||
|
* NULL,
|
||||||
* G_DBUS_CALL_FLAGS_NONE,
|
* G_DBUS_CALL_FLAGS_NONE,
|
||||||
* -1,
|
* -1,
|
||||||
* NULL,
|
* NULL,
|
||||||
@ -4190,6 +4300,7 @@ g_dbus_connection_call (GDBusConnection *connection,
|
|||||||
const gchar *interface_name,
|
const gchar *interface_name,
|
||||||
const gchar *method_name,
|
const gchar *method_name,
|
||||||
GVariant *parameters,
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
GDBusCallFlags flags,
|
GDBusCallFlags flags,
|
||||||
gint timeout_msec,
|
gint timeout_msec,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
@ -4197,6 +4308,7 @@ g_dbus_connection_call (GDBusConnection *connection,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GDBusMessage *message;
|
GDBusMessage *message;
|
||||||
|
CallState *state;
|
||||||
|
|
||||||
g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
|
g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
|
||||||
g_return_if_fail (bus_name == NULL || g_dbus_is_name (bus_name));
|
g_return_if_fail (bus_name == NULL || g_dbus_is_name (bus_name));
|
||||||
@ -4206,6 +4318,17 @@ g_dbus_connection_call (GDBusConnection *connection,
|
|||||||
g_return_if_fail (timeout_msec >= 0 || timeout_msec == -1);
|
g_return_if_fail (timeout_msec >= 0 || timeout_msec == -1);
|
||||||
g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
|
g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
|
||||||
|
|
||||||
|
state = g_slice_new (CallState);
|
||||||
|
state->simple = g_simple_async_result_new (G_OBJECT (connection),
|
||||||
|
callback, user_data,
|
||||||
|
g_dbus_connection_call);
|
||||||
|
state->method_name = g_strjoin (".", interface_name, method_name, NULL);
|
||||||
|
|
||||||
|
if (reply_type == NULL)
|
||||||
|
reply_type = G_VARIANT_TYPE_ANY;
|
||||||
|
|
||||||
|
state->reply_type = g_variant_type_copy (reply_type);
|
||||||
|
|
||||||
message = g_dbus_message_new_method_call (bus_name,
|
message = g_dbus_message_new_method_call (bus_name,
|
||||||
object_path,
|
object_path,
|
||||||
interface_name,
|
interface_name,
|
||||||
@ -4219,47 +4342,13 @@ g_dbus_connection_call (GDBusConnection *connection,
|
|||||||
timeout_msec,
|
timeout_msec,
|
||||||
NULL, /* volatile guint32 *out_serial */
|
NULL, /* volatile guint32 *out_serial */
|
||||||
cancellable,
|
cancellable,
|
||||||
callback,
|
g_dbus_connection_call_done,
|
||||||
user_data);
|
state);
|
||||||
|
|
||||||
if (message != NULL)
|
if (message != NULL)
|
||||||
g_object_unref (message);
|
g_object_unref (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GVariant *
|
|
||||||
decode_method_reply (GDBusMessage *reply,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
GVariant *result;
|
|
||||||
|
|
||||||
result = NULL;
|
|
||||||
switch (g_dbus_message_get_message_type (reply))
|
|
||||||
{
|
|
||||||
case G_DBUS_MESSAGE_TYPE_METHOD_RETURN:
|
|
||||||
result = g_dbus_message_get_body (reply);
|
|
||||||
if (result == NULL)
|
|
||||||
{
|
|
||||||
result = g_variant_new ("()");
|
|
||||||
g_variant_ref_sink (result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_variant_ref (result);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case G_DBUS_MESSAGE_TYPE_ERROR:
|
|
||||||
g_dbus_message_to_gerror (reply, error);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_dbus_connection_call_finish:
|
* g_dbus_connection_call_finish:
|
||||||
* @connection: A #GDBusConnection.
|
* @connection: A #GDBusConnection.
|
||||||
@ -4278,25 +4367,19 @@ g_dbus_connection_call_finish (GDBusConnection *connection,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GDBusMessage *reply;
|
GSimpleAsyncResult *simple;
|
||||||
GVariant *result;
|
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
|
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
|
||||||
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
|
g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (connection),
|
||||||
|
g_dbus_connection_call), NULL);
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
result = NULL;
|
simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||||
|
|
||||||
reply = g_dbus_connection_send_message_with_reply_finish (connection, res, error);
|
if (g_simple_async_result_propagate_error (simple, error))
|
||||||
if (reply == NULL)
|
return FALSE;
|
||||||
goto out;
|
|
||||||
|
|
||||||
result = decode_method_reply (reply, error);
|
return g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
||||||
|
|
||||||
g_object_unref (reply);
|
|
||||||
|
|
||||||
out:
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@ -4309,6 +4392,7 @@ g_dbus_connection_call_finish (GDBusConnection *connection,
|
|||||||
* @interface_name: D-Bus interface to invoke method on.
|
* @interface_name: D-Bus interface to invoke method on.
|
||||||
* @method_name: The name of the method to invoke.
|
* @method_name: The name of the method to invoke.
|
||||||
* @parameters: A #GVariant tuple with parameters for the method or %NULL if not passing parameters.
|
* @parameters: A #GVariant tuple with parameters for the method or %NULL if not passing parameters.
|
||||||
|
* @reply_type: The expected type of the reply, or %NULL.
|
||||||
* @flags: Flags from the #GDBusCallFlags enumeration.
|
* @flags: Flags from the #GDBusCallFlags enumeration.
|
||||||
* @timeout_msec: The timeout in milliseconds or -1 to use the default timeout.
|
* @timeout_msec: The timeout in milliseconds or -1 to use the default timeout.
|
||||||
* @cancellable: A #GCancellable or %NULL.
|
* @cancellable: A #GCancellable or %NULL.
|
||||||
@ -4323,6 +4407,11 @@ g_dbus_connection_call_finish (GDBusConnection *connection,
|
|||||||
* operation will fail with %G_IO_ERROR_CANCELLED. If @parameters
|
* operation will fail with %G_IO_ERROR_CANCELLED. If @parameters
|
||||||
* contains a value not compatible with the D-Bus protocol, the operation
|
* contains a value not compatible with the D-Bus protocol, the operation
|
||||||
* fails with %G_IO_ERROR_INVALID_ARGUMENT.
|
* fails with %G_IO_ERROR_INVALID_ARGUMENT.
|
||||||
|
|
||||||
|
* If @reply_type is non-%NULL then the reply will be checked for having
|
||||||
|
* this type and an error will be raised if it does not match. Said
|
||||||
|
* another way, if you give a @reply_type then any non-%NULL return
|
||||||
|
* value will be of this type.
|
||||||
*
|
*
|
||||||
* If the @parameters #GVariant is floating, it is consumed.
|
* If the @parameters #GVariant is floating, it is consumed.
|
||||||
* This allows convenient 'inline' use of g_variant_new(), e.g.:
|
* This allows convenient 'inline' use of g_variant_new(), e.g.:
|
||||||
@ -4335,6 +4424,7 @@ g_dbus_connection_call_finish (GDBusConnection *connection,
|
|||||||
* g_variant_new ("(ss)",
|
* g_variant_new ("(ss)",
|
||||||
* "Thing One",
|
* "Thing One",
|
||||||
* "Thing Two"),
|
* "Thing Two"),
|
||||||
|
* NULL,
|
||||||
* G_DBUS_CALL_FLAGS_NONE,
|
* G_DBUS_CALL_FLAGS_NONE,
|
||||||
* -1,
|
* -1,
|
||||||
* NULL,
|
* NULL,
|
||||||
@ -4357,6 +4447,7 @@ g_dbus_connection_call_sync (GDBusConnection *connection,
|
|||||||
const gchar *interface_name,
|
const gchar *interface_name,
|
||||||
const gchar *method_name,
|
const gchar *method_name,
|
||||||
GVariant *parameters,
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
GDBusCallFlags flags,
|
GDBusCallFlags flags,
|
||||||
gint timeout_msec,
|
gint timeout_msec,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
@ -4378,6 +4469,9 @@ g_dbus_connection_call_sync (GDBusConnection *connection,
|
|||||||
g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
|
g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
|
||||||
g_return_val_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
|
g_return_val_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
|
||||||
|
|
||||||
|
if (reply_type == NULL)
|
||||||
|
reply_type = G_VARIANT_TYPE_ANY;
|
||||||
|
|
||||||
message = g_dbus_message_new_method_call (bus_name,
|
message = g_dbus_message_new_method_call (bus_name,
|
||||||
object_path,
|
object_path,
|
||||||
interface_name,
|
interface_name,
|
||||||
@ -4396,7 +4490,7 @@ g_dbus_connection_call_sync (GDBusConnection *connection,
|
|||||||
if (reply == NULL)
|
if (reply == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
result = decode_method_reply (reply, error);
|
result = decode_method_reply (reply, method_name, reply_type, error);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (message != NULL)
|
if (message != NULL)
|
||||||
|
@ -179,6 +179,7 @@ void g_dbus_connection_call (GDBusConnection
|
|||||||
const gchar *interface_name,
|
const gchar *interface_name,
|
||||||
const gchar *method_name,
|
const gchar *method_name,
|
||||||
GVariant *parameters,
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
GDBusCallFlags flags,
|
GDBusCallFlags flags,
|
||||||
gint timeout_msec,
|
gint timeout_msec,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
@ -193,6 +194,7 @@ GVariant *g_dbus_connection_call_sync (GDBusConnection
|
|||||||
const gchar *interface_name,
|
const gchar *interface_name,
|
||||||
const gchar *method_name,
|
const gchar *method_name,
|
||||||
GVariant *parameters,
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
GDBusCallFlags flags,
|
GDBusCallFlags flags,
|
||||||
gint timeout_msec,
|
gint timeout_msec,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
@ -340,29 +340,27 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
|
|||||||
g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
|
g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
|
||||||
g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
|
g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
|
||||||
|
|
||||||
if (parameters != NULL)
|
if (parameters == NULL)
|
||||||
g_variant_ref_sink (parameters);
|
parameters = g_variant_new_tuple (NULL, 0);
|
||||||
|
|
||||||
/* if we have introspection data, check that the signature of @parameters is correct */
|
/* if we have introspection data, check that the signature of @parameters is correct */
|
||||||
if (invocation->priv->method_info != NULL)
|
if (invocation->priv->method_info != NULL)
|
||||||
{
|
{
|
||||||
gchar *signature;
|
GVariantType *type;
|
||||||
const gchar *type_string;
|
|
||||||
|
|
||||||
type_string = "()";
|
type = _g_dbus_compute_complete_signature (invocation->priv->method_info->out_args);
|
||||||
if (parameters != NULL)
|
|
||||||
type_string = g_variant_get_type_string (parameters);
|
|
||||||
signature = _g_dbus_compute_complete_signature (invocation->priv->method_info->out_args, TRUE);
|
|
||||||
|
|
||||||
if (g_strcmp0 (type_string, signature) != 0)
|
if (!g_variant_is_of_type (parameters, type))
|
||||||
{
|
{
|
||||||
g_warning (_("Type of return value is incorrect, got `%s', expected `%s'"),
|
gchar *type_string = g_variant_type_dup_string (type);
|
||||||
type_string,
|
|
||||||
signature);
|
g_warning (_("Type of return value is incorrect, got `%s', expected `%s'"),
|
||||||
g_free (signature);
|
g_variant_get_type_string (parameters), type_string);
|
||||||
|
g_variant_type_free (type);
|
||||||
|
g_free (type_string);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
g_free (signature);
|
g_variant_type_free (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
reply = g_dbus_message_new_method_reply (invocation->priv->message);
|
reply = g_dbus_message_new_method_reply (invocation->priv->message);
|
||||||
@ -377,8 +375,6 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
g_object_unref (invocation);
|
g_object_unref (invocation);
|
||||||
if (parameters != NULL)
|
|
||||||
g_variant_unref (parameters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
@ -403,6 +403,7 @@ has_connection (Client *client)
|
|||||||
g_variant_new ("(su)",
|
g_variant_new ("(su)",
|
||||||
client->name,
|
client->name,
|
||||||
client->flags),
|
client->flags),
|
||||||
|
G_VARIANT_TYPE ("(u)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
@ -681,6 +682,7 @@ g_bus_unown_name (guint owner_id)
|
|||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"ReleaseName", /* method name */
|
"ReleaseName", /* method name */
|
||||||
g_variant_new ("(s)", client->name),
|
g_variant_new ("(s)", client->name),
|
||||||
|
G_VARIANT_TYPE ("(u)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -368,6 +368,7 @@ invoke_get_name_owner (Client *client)
|
|||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetNameOwner", /* method name */
|
"GetNameOwner", /* method name */
|
||||||
g_variant_new ("(s)", client->name),
|
g_variant_new ("(s)", client->name),
|
||||||
|
G_VARIANT_TYPE ("(s)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
@ -459,6 +460,7 @@ has_connection (Client *client)
|
|||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"StartServiceByName", /* method name */
|
"StartServiceByName", /* method name */
|
||||||
g_variant_new ("(su)", client->name, 0),
|
g_variant_new ("(su)", client->name, 0),
|
||||||
|
G_VARIANT_TYPE ("(u)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -1035,25 +1035,29 @@ _g_dbus_initialize (void)
|
|||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
gchar *
|
GVariantType *
|
||||||
_g_dbus_compute_complete_signature (GDBusArgInfo **args,
|
_g_dbus_compute_complete_signature (GDBusArgInfo **args)
|
||||||
gboolean include_parentheses)
|
|
||||||
{
|
{
|
||||||
GString *s;
|
const GVariantType *arg_types[256];
|
||||||
guint n;
|
guint n;
|
||||||
|
|
||||||
if (include_parentheses)
|
if (args)
|
||||||
s = g_string_new ("(");
|
|
||||||
else
|
|
||||||
s = g_string_new ("");
|
|
||||||
if (args != NULL)
|
|
||||||
for (n = 0; args[n] != NULL; n++)
|
for (n = 0; args[n] != NULL; n++)
|
||||||
g_string_append (s, args[n]->signature);
|
{
|
||||||
|
/* DBus places a hard limit of 255 on signature length.
|
||||||
|
* therefore number of args must be less than 256.
|
||||||
|
*/
|
||||||
|
g_assert (n < 256);
|
||||||
|
|
||||||
if (include_parentheses)
|
arg_types[n] = G_VARIANT_TYPE (args[n]->signature);
|
||||||
g_string_append_c (s, ')');
|
|
||||||
|
|
||||||
return g_string_free (s, FALSE);
|
if G_UNLIKELY (arg_types[n] == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
return g_variant_type_new_tuple (arg_types, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
@ -73,8 +73,7 @@ gboolean _g_dbus_address_parse_entry (const gchar *address_entry,
|
|||||||
GHashTable **out_key_value_pairs,
|
GHashTable **out_key_value_pairs,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
gchar * _g_dbus_compute_complete_signature (GDBusArgInfo **args,
|
GVariantType * _g_dbus_compute_complete_signature (GDBusArgInfo **args);
|
||||||
gboolean include_parentheses);
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -845,6 +845,7 @@ initable_init (GInitable *initable,
|
|||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"GetAll",
|
"GetAll",
|
||||||
g_variant_new ("(s)", proxy->priv->interface_name),
|
g_variant_new ("(s)", proxy->priv->interface_name),
|
||||||
|
G_VARIANT_TYPE ("(a{sv})"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1, /* timeout */
|
-1, /* timeout */
|
||||||
cancellable,
|
cancellable,
|
||||||
@ -927,6 +928,7 @@ async_initable_init_async (GAsyncInitable *initable,
|
|||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"GetAll",
|
"GetAll",
|
||||||
g_variant_new ("(s)", proxy->priv->interface_name),
|
g_variant_new ("(s)", proxy->priv->interface_name),
|
||||||
|
G_VARIANT_TYPE ("(a{sv})"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1, /* timeout */
|
-1, /* timeout */
|
||||||
cancellable,
|
cancellable,
|
||||||
@ -1408,45 +1410,6 @@ lookup_method_info_or_warn (GDBusProxy *proxy,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
validate_method_return (const char *method_name,
|
|
||||||
GVariant *value,
|
|
||||||
const GDBusMethodInfo *expected_method_info,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
const gchar *type_string;
|
|
||||||
gchar *signature;
|
|
||||||
gboolean ret;
|
|
||||||
|
|
||||||
ret = TRUE;
|
|
||||||
signature = NULL;
|
|
||||||
|
|
||||||
if (value == NULL || expected_method_info == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* Shouldn't happen... */
|
|
||||||
if (g_variant_classify (value) != G_VARIANT_CLASS_TUPLE)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
type_string = g_variant_get_type_string (value);
|
|
||||||
signature = _g_dbus_compute_complete_signature (expected_method_info->out_args, TRUE);
|
|
||||||
if (g_strcmp0 (type_string, signature) != 0)
|
|
||||||
{
|
|
||||||
g_set_error (error,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
|
||||||
_("Method `%s' returned signature `%s', but expected `%s'"),
|
|
||||||
method_name,
|
|
||||||
type_string,
|
|
||||||
signature);
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
g_free (signature);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_dbus_proxy_call:
|
* g_dbus_proxy_call:
|
||||||
* @proxy: A #GDBusProxy.
|
* @proxy: A #GDBusProxy.
|
||||||
@ -1514,6 +1477,7 @@ g_dbus_proxy_call (GDBusProxy *proxy,
|
|||||||
const GDBusMethodInfo *expected_method_info;
|
const GDBusMethodInfo *expected_method_info;
|
||||||
const gchar *target_method_name;
|
const gchar *target_method_name;
|
||||||
const gchar *target_interface_name;
|
const gchar *target_interface_name;
|
||||||
|
GVariantType *reply_type;
|
||||||
|
|
||||||
g_return_if_fail (G_IS_DBUS_PROXY (proxy));
|
g_return_if_fail (G_IS_DBUS_PROXY (proxy));
|
||||||
g_return_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name));
|
g_return_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name));
|
||||||
@ -1534,18 +1498,27 @@ g_dbus_proxy_call (GDBusProxy *proxy,
|
|||||||
/* Just warn here */
|
/* Just warn here */
|
||||||
expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
|
expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
|
||||||
|
|
||||||
|
if (expected_method_info)
|
||||||
|
reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
|
||||||
|
else
|
||||||
|
reply_type = NULL;
|
||||||
|
|
||||||
g_dbus_connection_call (proxy->priv->connection,
|
g_dbus_connection_call (proxy->priv->connection,
|
||||||
proxy->priv->unique_bus_name,
|
proxy->priv->unique_bus_name,
|
||||||
proxy->priv->object_path,
|
proxy->priv->object_path,
|
||||||
target_interface_name,
|
target_interface_name,
|
||||||
target_method_name,
|
target_method_name,
|
||||||
parameters,
|
parameters,
|
||||||
|
reply_type,
|
||||||
flags,
|
flags,
|
||||||
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
||||||
cancellable,
|
cancellable,
|
||||||
(GAsyncReadyCallback) reply_cb,
|
(GAsyncReadyCallback) reply_cb,
|
||||||
simple);
|
simple);
|
||||||
|
|
||||||
|
if (reply_type != NULL)
|
||||||
|
g_variant_type_free (reply_type);
|
||||||
|
|
||||||
g_free (split_interface_name);
|
g_free (split_interface_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1570,7 +1543,6 @@ g_dbus_proxy_call_finish (GDBusProxy *proxy,
|
|||||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||||
GVariant *value;
|
GVariant *value;
|
||||||
const char *method_name;
|
const char *method_name;
|
||||||
const GDBusMethodInfo *expected_method_info;
|
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
|
g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
|
||||||
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
|
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
|
||||||
@ -1586,17 +1558,6 @@ g_dbus_proxy_call_finish (GDBusProxy *proxy,
|
|||||||
value = g_simple_async_result_get_op_res_gpointer (simple);
|
value = g_simple_async_result_get_op_res_gpointer (simple);
|
||||||
method_name = g_object_get_data (G_OBJECT (simple), "-gdbus-proxy-method-name");
|
method_name = g_object_get_data (G_OBJECT (simple), "-gdbus-proxy-method-name");
|
||||||
|
|
||||||
/* We may not have a method name for internally-generated proxy calls like GetAll */
|
|
||||||
if (value && method_name && proxy->priv->expected_interface)
|
|
||||||
{
|
|
||||||
expected_method_info = g_dbus_interface_info_lookup_method (proxy->priv->expected_interface, method_name);
|
|
||||||
if (!validate_method_return (method_name, value, expected_method_info, error))
|
|
||||||
{
|
|
||||||
g_variant_unref (value);
|
|
||||||
value = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -1663,6 +1624,7 @@ g_dbus_proxy_call_sync (GDBusProxy *proxy,
|
|||||||
const GDBusMethodInfo *expected_method_info;
|
const GDBusMethodInfo *expected_method_info;
|
||||||
const gchar *target_method_name;
|
const gchar *target_method_name;
|
||||||
const gchar *target_interface_name;
|
const gchar *target_interface_name;
|
||||||
|
GVariantType *reply_type;
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
|
g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
|
||||||
g_return_val_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name), NULL);
|
g_return_val_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name), NULL);
|
||||||
@ -1689,21 +1651,25 @@ g_dbus_proxy_call_sync (GDBusProxy *proxy,
|
|||||||
expected_method_info = NULL;
|
expected_method_info = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (expected_method_info)
|
||||||
|
reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
|
||||||
|
else
|
||||||
|
reply_type = NULL;
|
||||||
|
|
||||||
ret = g_dbus_connection_call_sync (proxy->priv->connection,
|
ret = g_dbus_connection_call_sync (proxy->priv->connection,
|
||||||
proxy->priv->unique_bus_name,
|
proxy->priv->unique_bus_name,
|
||||||
proxy->priv->object_path,
|
proxy->priv->object_path,
|
||||||
target_interface_name,
|
target_interface_name,
|
||||||
target_method_name,
|
target_method_name,
|
||||||
parameters,
|
parameters,
|
||||||
|
reply_type,
|
||||||
flags,
|
flags,
|
||||||
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
||||||
cancellable,
|
cancellable,
|
||||||
error);
|
error);
|
||||||
if (!validate_method_return (target_method_name, ret, expected_method_info, error))
|
|
||||||
{
|
if (reply_type != NULL)
|
||||||
g_variant_unref (ret);
|
g_variant_type_free (reply_type);
|
||||||
ret = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (split_interface_name);
|
g_free (split_interface_name);
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ handle_set (gint *argc,
|
|||||||
session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||||
g_dbus_connection_call_sync (session, "org.gtk.DoesNotExist", "/",
|
g_dbus_connection_call_sync (session, "org.gtk.DoesNotExist", "/",
|
||||||
"org.gtk.DoesNotExist", "Workaround",
|
"org.gtk.DoesNotExist", "Workaround",
|
||||||
g_variant_new ("()"), 0, -1, NULL, NULL);
|
g_variant_new ("()"), NULL, 0, -1, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -234,7 +234,7 @@ test_connection_send (void)
|
|||||||
"/org/freedesktop/DBus", /* object path */
|
"/org/freedesktop/DBus", /* object path */
|
||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetId", /* method name */
|
"GetId", /* method name */
|
||||||
NULL,
|
NULL, NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
ca,
|
ca,
|
||||||
@ -251,7 +251,7 @@ test_connection_send (void)
|
|||||||
"/org/freedesktop/DBus", /* object path */
|
"/org/freedesktop/DBus", /* object path */
|
||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetId", /* method name */
|
"GetId", /* method name */
|
||||||
NULL,
|
NULL, NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
@ -267,7 +267,7 @@ test_connection_send (void)
|
|||||||
"/org/freedesktop/DBus", /* object path */
|
"/org/freedesktop/DBus", /* object path */
|
||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"NonExistantMethod", /* method name */
|
"NonExistantMethod", /* method name */
|
||||||
NULL,
|
NULL, NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
@ -284,7 +284,7 @@ test_connection_send (void)
|
|||||||
"/org/freedesktop/DBus", /* object path */
|
"/org/freedesktop/DBus", /* object path */
|
||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetId", /* method name */
|
"GetId", /* method name */
|
||||||
NULL,
|
NULL, NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
ca,
|
ca,
|
||||||
@ -307,7 +307,7 @@ test_connection_send (void)
|
|||||||
"/org/freedesktop/DBus", /* object path */
|
"/org/freedesktop/DBus", /* object path */
|
||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetId", /* method name */
|
"GetId", /* method name */
|
||||||
NULL,
|
NULL, NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
@ -462,6 +462,7 @@ test_connection_signals (void)
|
|||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetId", /* method name */
|
"GetId", /* method name */
|
||||||
NULL, /* parameters */
|
NULL, /* parameters */
|
||||||
|
NULL, /* return type */
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -280,6 +280,7 @@ main (int argc, char *argv[])
|
|||||||
"org.gtk.GDBus.TestPeerInterface",
|
"org.gtk.GDBus.TestPeerInterface",
|
||||||
"HelloWorld",
|
"HelloWorld",
|
||||||
g_variant_new ("(s)", greeting),
|
g_variant_new ("(s)", greeting),
|
||||||
|
G_VARIANT_TYPE ("(s)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -807,7 +807,7 @@ test_dispatch_thread_func (gpointer user_data)
|
|||||||
NULL,
|
NULL,
|
||||||
&error);
|
&error);
|
||||||
g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS);
|
g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS);
|
||||||
g_assert_cmpstr (error->message, ==, "GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Signature of message, `s', does not match expected signature `'");
|
g_assert_cmpstr (error->message, ==, "GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Type of message, `(s)', does not match expected type `()'");
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
g_assert (value == NULL);
|
g_assert (value == NULL);
|
||||||
|
|
||||||
|
@ -176,6 +176,7 @@ test_bus_own_name (void)
|
|||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"NameHasOwner", /* method name */
|
"NameHasOwner", /* method name */
|
||||||
g_variant_new ("(s)", name),
|
g_variant_new ("(s)", name),
|
||||||
|
G_VARIANT_TYPE ("(b)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
@ -201,6 +202,7 @@ test_bus_own_name (void)
|
|||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"NameHasOwner", /* method name */
|
"NameHasOwner", /* method name */
|
||||||
g_variant_new ("(s)", name),
|
g_variant_new ("(s)", name),
|
||||||
|
G_VARIANT_TYPE ("(b)"),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -136,7 +136,7 @@ test_delivery_in_thread_func (gpointer _data)
|
|||||||
"/org/freedesktop/DBus", /* object path */
|
"/org/freedesktop/DBus", /* object path */
|
||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetId", /* method name */
|
"GetId", /* method name */
|
||||||
NULL,
|
NULL, NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
@ -156,7 +156,7 @@ test_delivery_in_thread_func (gpointer _data)
|
|||||||
"/org/freedesktop/DBus", /* object path */
|
"/org/freedesktop/DBus", /* object path */
|
||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetId", /* method name */
|
"GetId", /* method name */
|
||||||
NULL,
|
NULL, NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
ca,
|
ca,
|
||||||
@ -174,7 +174,7 @@ test_delivery_in_thread_func (gpointer _data)
|
|||||||
"/org/freedesktop/DBus", /* object path */
|
"/org/freedesktop/DBus", /* object path */
|
||||||
"org.freedesktop.DBus", /* interface name */
|
"org.freedesktop.DBus", /* interface name */
|
||||||
"GetId", /* method name */
|
"GetId", /* method name */
|
||||||
NULL,
|
NULL, NULL,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
ca,
|
ca,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user