From 8b8141305feb1fee42b14fb9de16c619ae911152 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Sat, 13 Apr 2013 22:16:24 +0300 Subject: [PATCH] tools: Fix mpris-player not forwarding method calls properly This fixes not sending methods calls to players, it now copies the contents of the original message into the copy instead of relying on dbus_message_copy and send the reply back. --- tools/mpris-player.c | 140 ++++++++++++++++++++++++++++++------------- 1 file changed, 97 insertions(+), 43 deletions(-) diff --git a/tools/mpris-player.c b/tools/mpris-player.c index 2a39fb8fb..a7a506cda 100644 --- a/tools/mpris-player.c +++ b/tools/mpris-player.c @@ -170,44 +170,71 @@ static void dict_append_array(DBusMessageIter *dict, const char *key, int type, dbus_message_iter_close_container(dict, &entry); } -static int parse_metadata_entry(DBusMessageIter *entry, const char *key, - DBusMessageIter *metadata) +static void append_iter(DBusMessageIter *base, DBusMessageIter *iter) { - DBusMessageIter var; int type; - if (dbus_message_iter_get_arg_type(entry) != DBUS_TYPE_VARIANT) - return -EINVAL; + type = dbus_message_iter_get_arg_type(iter); - dbus_message_iter_recurse(entry, &var); + if (dbus_type_is_basic(type)) { + const void *value; - type = dbus_message_iter_get_arg_type(&var); - if (type == DBUS_TYPE_ARRAY) { - char **values; - int i; - DBusMessageIter array; + dbus_message_iter_get_basic(iter, &value); + dbus_message_iter_append_basic(base, type, &value); + } else if (dbus_type_is_container(type)) { + DBusMessageIter iter_sub, base_sub; + char *sig; + + dbus_message_iter_recurse(iter, &iter_sub); + + switch (type) { + case DBUS_TYPE_ARRAY: + case DBUS_TYPE_VARIANT: + sig = dbus_message_iter_get_signature(&iter_sub); + break; + default: + sig = NULL; + break; + } - dbus_message_iter_recurse(&var, &array); + dbus_message_iter_open_container(base, type, sig, &base_sub); - values = dbus_malloc0(sizeof(char *) * 8); + if (sig != NULL) + dbus_free(sig); - i = 0; - while (dbus_message_iter_get_arg_type(&array) != + while (dbus_message_iter_get_arg_type(&iter_sub) != DBUS_TYPE_INVALID) { - dbus_message_iter_get_basic(&array, &(values[i++])); - dbus_message_iter_next(&array); + append_iter(&base_sub, &iter_sub); + dbus_message_iter_next(&iter_sub); } - dict_append_array(metadata, key, DBUS_TYPE_STRING, &values, i); - dbus_free(values); - } else if (dbus_type_is_basic(type)) { - const void *value; + dbus_message_iter_close_container(base, &base_sub); + } +} - dbus_message_iter_get_basic(&var, &value); - dict_append_entry(metadata, key, type, &value); - } else +static void dict_append_iter(DBusMessageIter *dict, const char *key, + DBusMessageIter *iter) +{ + DBusMessageIter entry; + + dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, + NULL, &entry); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); + + append_iter(&entry, iter); + + dbus_message_iter_close_container(dict, &entry); +} + +static int parse_metadata_entry(DBusMessageIter *entry, const char *key, + DBusMessageIter *metadata) +{ + if (dbus_message_iter_get_arg_type(entry) != DBUS_TYPE_VARIANT) return -EINVAL; + dict_append_iter(metadata, key, entry); + return 0; } @@ -419,35 +446,62 @@ static char *sender2path(const char *sender) return g_strdelimit(path, ":.", '_'); } +static void copy_reply(DBusPendingCall *call, void *user_data) +{ + DBusMessage *msg = user_data; + DBusMessage *reply = dbus_pending_call_steal_reply(call); + DBusMessage *copy; + DBusMessageIter args, iter; + + copy = dbus_message_new_method_return(msg); + if (copy == NULL) { + dbus_message_unref(reply); + return; + } + + dbus_message_iter_init_append(msg, &iter); + + if (!dbus_message_iter_init(reply, &args)) + goto done; + + append_iter(&iter, &args); + + dbus_connection_send(sys, copy, NULL); + +done: + dbus_message_unref(copy); + dbus_message_unref(reply); +} + static DBusHandlerResult player_message(DBusConnection *conn, DBusMessage *msg, void *data) { char *owner = data; - dbus_uint32_t serial; - DBusMessage *copy, *reply; - DBusError err; + DBusMessage *copy; + DBusMessageIter args, iter; + DBusPendingCall *call; - copy = dbus_message_copy(msg); - dbus_message_set_destination(copy, owner); - reply = dbus_connection_send_with_reply_and_block(session, copy, -1, - &err); - if (!reply) { - if (dbus_error_is_set(&err)) { - fprintf(stderr, "%s\n", err.message); - dbus_error_free(&err); - } - dbus_message_unref(copy); + dbus_message_iter_init(msg, &args); + + copy = dbus_message_new_method_call(owner, + MPRIS_PLAYER_PATH, + dbus_message_get_interface(msg), + dbus_message_get_member(msg)); + if (copy == NULL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - dbus_message_unref(copy); + dbus_message_iter_init_append(msg, &iter); + append_iter(&iter, &args); - copy = dbus_message_copy(reply); - serial = dbus_message_get_serial(msg); - dbus_message_set_serial(copy, serial); + if (!dbus_connection_send_with_reply(session, copy, &call, -1)) + goto done; + dbus_message_ref(msg); + dbus_pending_call_set_notify(call, copy_reply, msg, NULL); + dbus_pending_call_unref(call); + +done: dbus_message_unref(copy); - dbus_message_unref(reply); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -- 2.47.3