From 945504454cafceeaba497e4e3afba07c405ced7d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 14 Sep 2012 14:45:38 +0100 Subject: [PATCH 13/21] Generally use GVariant, not GHashTable, for channels' properties This means we can avoid the deprecated tp_channel_borrow_immutable_properties(). Signed-off-by: Simon McVittie Bug: https://bugs.freedesktop.org/show_bug.cgi?id=55391 --- src/channel-utils.c | 24 +++++++++++------------ src/client-registry.c | 9 +++++---- src/client-registry.h | 2 +- src/mcd-channel-priv.h | 3 --- src/mcd-channel.c | 12 ++++++------ src/mcd-channel.h | 2 ++ src/mcd-client-priv.h | 2 +- src/mcd-client.c | 13 +++++++++++-- src/mcd-dispatch-operation.c | 12 ++++++++---- src/mcd-dispatcher.c | 41 +++++++++++++++++++++++++++------------ src/plugin-dispatch-operation.c | 14 ++++++++++--- src/request.c | 29 +++++++++++++++++++++++++-- src/request.h | 1 + 13 files changed, 113 insertions(+), 51 deletions(-) diff --git a/src/channel-utils.c b/src/channel-utils.c index 492b54b..a0cbe5e 100644 --- a/src/channel-utils.c +++ b/src/channel-utils.c @@ -83,19 +83,17 @@ _channel_details_array_append (GPtrArray *channel_array, TpChannel *channel) { GType type = TP_STRUCT_TYPE_CHANNEL_DETAILS; GValue channel_val = G_VALUE_INIT; - GHashTable *properties; - const gchar *object_path; - - properties = tp_channel_borrow_immutable_properties (channel); - object_path = tp_proxy_get_object_path (channel); - - g_value_init (&channel_val, type); - g_value_take_boxed (&channel_val, - dbus_g_type_specialized_construct (type)); - dbus_g_type_struct_set (&channel_val, - 0, object_path, - 1, properties, - G_MAXUINT); + GVariant *pair[2]; + GVariant *tuple; + + pair[0] = g_variant_new_object_path (tp_proxy_get_object_path (channel)); + pair[1] = tp_channel_dup_immutable_properties (channel); + /* takes ownership of floating pair[0] */ + tuple = g_variant_new_tuple (pair, 2); + dbus_g_value_parse_g_variant (tuple, &channel_val); + g_variant_unref (pair[1]); + g_variant_unref (tuple); + g_assert (G_VALUE_HOLDS (&channel_val, type)); g_ptr_array_add (channel_array, g_value_get_boxed (&channel_val)); } diff --git a/src/client-registry.c b/src/client-registry.c index acc65e7..8cc987c 100644 --- a/src/client-registry.c +++ b/src/client-registry.c @@ -603,7 +603,7 @@ possible_handler_cmp (gconstpointer a_, GList * _mcd_client_registry_list_possible_handlers (McdClientRegistry *self, const gchar *preferred_handler, - GHashTable *request_props, + GVariant *request_props, TpChannel *channel, const gchar *must_have_unique_name) { @@ -617,7 +617,6 @@ _mcd_client_registry_list_possible_handlers (McdClientRegistry *self, while (g_hash_table_iter_next (&client_iter, NULL, &client_p)) { McdClientProxy *client = MCD_CLIENT_PROXY (client_p); - GHashTable *properties; gsize quality; if (must_have_unique_name != NULL && @@ -649,11 +648,13 @@ _mcd_client_registry_list_possible_handlers (McdClientRegistry *self, } else { - g_assert (TP_IS_CHANNEL (channel)); - properties = tp_channel_borrow_immutable_properties (channel); + GVariant *properties; + g_assert (TP_IS_CHANNEL (channel)); + properties = tp_channel_dup_immutable_properties (channel); quality = _mcd_client_match_filters (properties, _mcd_client_proxy_get_handler_filters (client), FALSE); + g_variant_unref (properties); } if (quality > 0) diff --git a/src/client-registry.h b/src/client-registry.h index ec2e167..fb81f6d 100644 --- a/src/client-registry.h +++ b/src/client-registry.h @@ -82,7 +82,7 @@ G_GNUC_INTERNAL void _mcd_client_registry_init_hash_iter ( G_GNUC_INTERNAL GList *_mcd_client_registry_list_possible_handlers ( McdClientRegistry *self, const gchar *preferred_handler, - GHashTable *request_props, TpChannel *channel, + GVariant *request_props, TpChannel *channel, const gchar *must_have_unique_name); G_END_DECLS diff --git a/src/mcd-channel-priv.h b/src/mcd-channel-priv.h index a5893aa..b45ad31 100644 --- a/src/mcd-channel-priv.h +++ b/src/mcd-channel-priv.h @@ -45,9 +45,6 @@ void _mcd_channel_set_status (McdChannel *channel, McdChannelStatus status); /* not exported: */ G_GNUC_INTERNAL void _mcd_channel_undispatchable (McdChannel *self); -G_GNUC_INTERNAL -GHashTable *_mcd_channel_get_immutable_properties (McdChannel *channel); - G_GNUC_INTERNAL McdRequest *_mcd_channel_get_request (McdChannel *self); G_GNUC_INTERNAL diff --git a/src/mcd-channel.c b/src/mcd-channel.c index 4310ba0..b454480 100644 --- a/src/mcd-channel.c +++ b/src/mcd-channel.c @@ -737,15 +737,15 @@ mcd_channel_get_object_path (McdChannel *channel) } /* - * _mcd_channel_get_immutable_properties: + * mcd_channel_dup_immutable_properties: * @channel: the #McdChannel. * - * Returns: the #GHashTable of the immutable properties. + * Returns: the %G_VARIANT_TYPE_VARDICT of the immutable properties. */ -GHashTable * -_mcd_channel_get_immutable_properties (McdChannel *channel) +GVariant * +mcd_channel_dup_immutable_properties (McdChannel *channel) { - GHashTable *ret; + GVariant *ret; g_return_val_if_fail (MCD_IS_CHANNEL (channel), NULL); @@ -755,7 +755,7 @@ _mcd_channel_get_immutable_properties (McdChannel *channel) return NULL; } - ret = tp_channel_borrow_immutable_properties (channel->priv->tp_chan); + ret = tp_channel_dup_immutable_properties (channel->priv->tp_chan); if (ret == NULL) { diff --git a/src/mcd-channel.h b/src/mcd-channel.h index cdfac24..797233f 100644 --- a/src/mcd-channel.h +++ b/src/mcd-channel.h @@ -108,5 +108,7 @@ TpChannel *mcd_channel_get_tp_channel (McdChannel *channel); void mcd_channel_take_error (McdChannel *channel, GError *error); const GError *mcd_channel_get_error (McdChannel *channel); +GVariant *mcd_channel_dup_immutable_properties (McdChannel *channel); + G_END_DECLS #endif /* MCD_CHANNEL_H */ diff --git a/src/mcd-client-priv.h b/src/mcd-client-priv.h index 59275d0..8b300a6 100644 --- a/src/mcd-client-priv.h +++ b/src/mcd-client-priv.h @@ -115,7 +115,7 @@ G_GNUC_INTERNAL gboolean _mcd_client_match_property ( GValue *filter_value); G_GNUC_INTERNAL guint _mcd_client_match_filters ( - GHashTable *channel_properties, const GList *filters, + GVariant *channel_properties, const GList *filters, gboolean assume_requested); G_GNUC_INTERNAL void _mcd_client_proxy_handle_channels (McdClientProxy *self, diff --git a/src/mcd-client.c b/src/mcd-client.c index 565347f..efdcf56 100644 --- a/src/mcd-client.c +++ b/src/mcd-client.c @@ -1559,12 +1559,19 @@ _mcd_client_match_property (GHashTable *channel_properties, * largest filter that matched) */ guint -_mcd_client_match_filters (GHashTable *channel_properties, +_mcd_client_match_filters (GVariant *channel_properties, const GList *filters, gboolean assume_requested) { const GList *list; guint best_quality = 0; + GValue value = G_VALUE_INIT; + + /* FIXME: when Xavier's tp_vardict_get_*() functions have landed, + * make _mcd_client_match_property use those on variant_properties + * rather than doing this. But for now... */ + dbus_g_value_parse_g_variant (channel_properties, &value); + g_assert (G_VALUE_HOLDS (&value, TP_HASH_TYPE_STRING_VARIANT_MAP)); for (list = filters; list != NULL; list = list->next) { @@ -1600,7 +1607,7 @@ _mcd_client_match_filters (GHashTable *channel_properties, break; } } - else if (! _mcd_client_match_property (channel_properties, + else if (! _mcd_client_match_property (g_value_get_boxed (&value), property_name, filter_value)) { @@ -1615,6 +1622,8 @@ _mcd_client_match_filters (GHashTable *channel_properties, } } + g_value_unset (&value); + return best_quality; } diff --git a/src/mcd-dispatch-operation.c b/src/mcd-dispatch-operation.c index ac036f0..8df17cb 100644 --- a/src/mcd-dispatch-operation.c +++ b/src/mcd-dispatch-operation.c @@ -2048,15 +2048,17 @@ _mcd_dispatch_operation_run_observers (McdDispatchOperation *self) if (self->priv->channel != NULL) { McdChannel *channel = MCD_CHANNEL (self->priv->channel); - GHashTable *properties; + GVariant *properties; - properties = _mcd_channel_get_immutable_properties (channel); + properties = mcd_channel_dup_immutable_properties (channel); g_assert (properties != NULL); if (_mcd_client_match_filters (properties, _mcd_client_proxy_get_observer_filters (client), FALSE)) observed = TRUE; + + g_variant_unref (properties); } /* in particular this happens if there is no channel at all */ @@ -2166,9 +2168,9 @@ _mcd_dispatch_operation_run_approvers (McdDispatchOperation *self) if (self->priv->channel != NULL) { McdChannel *channel = MCD_CHANNEL (self->priv->channel); - GHashTable *channel_properties; + GVariant *channel_properties; - channel_properties = _mcd_channel_get_immutable_properties (channel); + channel_properties = mcd_channel_dup_immutable_properties (channel); g_assert (channel_properties != NULL); if (_mcd_client_match_filters (channel_properties, @@ -2177,6 +2179,8 @@ _mcd_dispatch_operation_run_approvers (McdDispatchOperation *self) { matched = TRUE; } + + g_variant_unref (channel_properties); } /* in particular, after this point, self->priv->channel can't diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c index 23c943d..caa7007 100644 --- a/src/mcd-dispatcher.c +++ b/src/mcd-dispatcher.c @@ -181,15 +181,24 @@ mcd_dispatcher_dup_possible_handlers (McdDispatcher *self, TpChannel *channel, const gchar *must_have_unique_name) { - GList *handlers = _mcd_client_registry_list_possible_handlers ( - self->priv->clients, - request != NULL ? _mcd_request_get_preferred_handler (request) : NULL, - request != NULL ? _mcd_request_get_properties (request) : NULL, - channel, must_have_unique_name); - guint n_handlers = g_list_length (handlers); + GList *handlers; + guint n_handlers; guint i; GStrv ret; const GList *iter; + GVariant *request_properties = NULL; + + if (request != NULL) + request_properties = mcd_request_dup_properties (request); + + handlers = _mcd_client_registry_list_possible_handlers ( + self->priv->clients, + request != NULL ? _mcd_request_get_preferred_handler (request) : NULL, + request_properties, + channel, must_have_unique_name); + n_handlers = g_list_length (handlers); + + tp_clear_pointer (&request_properties, g_variant_unref); if (handlers == NULL) return NULL; @@ -532,6 +541,7 @@ _mcd_dispatcher_lookup_handler (McdDispatcher *self, if (handler == NULL) { GList *possible_handlers; + GVariant *request_properties = NULL; /* Failing that, maybe the Handler it was dispatched to was temporary; * try to pick another Handler that can deal with it, on the same @@ -539,11 +549,14 @@ _mcd_dispatcher_lookup_handler (McdDispatcher *self, * It can also happen in the case an Observer/Approver Claimed the * channel; in that case we did not get its handler well known name. */ + if (request != NULL) + request_properties = mcd_request_dup_properties (request); + possible_handlers = _mcd_client_registry_list_possible_handlers ( self->priv->clients, request != NULL ? _mcd_request_get_preferred_handler (request) : NULL, - request != NULL ? _mcd_request_get_properties (request) : NULL, - channel, unique_name); + request_properties, channel, unique_name); + tp_clear_pointer (&request_properties, g_variant_unref); if (possible_handlers != NULL) { @@ -583,7 +596,7 @@ mcd_dispatcher_client_needs_recovery_cb (McdClientProxy *client, { TpChannel *channel = list->data; const gchar *object_path = tp_proxy_get_object_path (channel); - GHashTable *properties; + GVariant *properties; McdClientProxy *handler; /* FIXME: This is not exactly the right behaviour, see fd.o#40305 */ @@ -594,7 +607,7 @@ mcd_dispatcher_client_needs_recovery_cb (McdClientProxy *client, continue; } - properties = tp_channel_borrow_immutable_properties (channel); + properties = tp_channel_dup_immutable_properties (channel); if (_mcd_client_match_filters (properties, observer_filters, FALSE)) @@ -605,6 +618,8 @@ mcd_dispatcher_client_needs_recovery_cb (McdClientProxy *client, _mcd_client_recover_observer (client, channel, account_path); } + + g_variant_unref (properties); } /* we also need to think about channels that are still being dispatched, @@ -620,8 +635,8 @@ mcd_dispatcher_client_needs_recovery_cb (McdClientProxy *client, if (mcd_channel != NULL) { - GHashTable *properties = - _mcd_channel_get_immutable_properties (mcd_channel); + GVariant *properties = + mcd_channel_dup_immutable_properties (mcd_channel); if (_mcd_client_match_filters (properties, observer_filters, FALSE)) @@ -630,6 +645,8 @@ mcd_dispatcher_client_needs_recovery_cb (McdClientProxy *client, mcd_channel_get_tp_channel (mcd_channel), _mcd_dispatch_operation_get_account_path (op)); } + + g_variant_unref (properties); } } } diff --git a/src/plugin-dispatch-operation.c b/src/plugin-dispatch-operation.c index 0281dbf..cd9c279 100644 --- a/src/plugin-dispatch-operation.c +++ b/src/plugin-dispatch-operation.c @@ -208,6 +208,8 @@ plugin_do_ref_nth_channel_properties (McpDispatchOperation *obj, { McdPluginDispatchOperation *self = MCD_PLUGIN_DISPATCH_OPERATION (obj); McdChannel *channel; + GVariant *variant; + GValue value = G_VALUE_INIT; GHashTable *ret; g_return_val_if_fail (self != NULL, NULL); @@ -217,10 +219,16 @@ plugin_do_ref_nth_channel_properties (McpDispatchOperation *obj, if (channel == NULL || n != 0) return NULL; - ret = _mcd_channel_get_immutable_properties (channel); + variant = mcd_channel_dup_immutable_properties (channel); - if (ret != NULL) - g_hash_table_ref (ret); + if (variant == NULL) + return NULL; + + /* For compatibility, we have to return the older type here. */ + dbus_g_value_parse_g_variant (variant, &value); + g_assert (G_VALUE_HOLDS (&value, TP_HASH_TYPE_STRING_VARIANT_MAP)); + ret = g_value_dup_boxed (&value); + g_value_unset (&value); return ret; } diff --git a/src/request.c b/src/request.c index 410a98e..ce91440 100644 --- a/src/request.c +++ b/src/request.c @@ -762,6 +762,19 @@ _mcd_request_get_properties (McdRequest *self) return self->properties; } +GVariant * +mcd_request_dup_properties (McdRequest *self) +{ + GValue value = G_VALUE_INIT; + GVariant *ret; + + g_value_init (&value, TP_HASH_TYPE_STRING_VARIANT_MAP); + g_value_set_boxed (&value, self->properties); + ret = dbus_g_value_build_g_variant (&value); + g_value_unset (&value); + return g_variant_ref_sink (ret); +} + void _mcd_request_start_delay (McdRequest *self) { @@ -801,18 +814,27 @@ _mcd_request_set_success (McdRequest *self, * for now */ GHashTable *future_conn_props = g_hash_table_new (g_str_hash, g_str_equal); + GVariant *variant; + GValue value = G_VALUE_INIT; + DEBUG ("Request succeeded"); self->is_complete = TRUE; self->cancellable = FALSE; + variant = tp_channel_dup_immutable_properties (channel); + dbus_g_value_parse_g_variant (variant, &value); + g_assert (G_VALUE_HOLDS (&value, TP_HASH_TYPE_STRING_VARIANT_MAP)); + tp_svc_channel_request_emit_succeeded_with_channel (self, tp_proxy_get_object_path (tp_channel_get_connection (channel)), future_conn_props, tp_proxy_get_object_path (channel), - tp_channel_borrow_immutable_properties (channel)); + g_value_get_boxed (&value)); tp_svc_channel_request_emit_succeeded (self); g_hash_table_unref (future_conn_props); + g_value_unset (&value); + g_variant_unref (variant); _mcd_request_clean_up (self); } @@ -963,6 +985,7 @@ static TpClient * guess_request_handler (McdRequest *self) { GList *sorted_handlers; + GVariant *properties; if (!tp_str_empty (self->preferred_handler)) { @@ -973,9 +996,11 @@ guess_request_handler (McdRequest *self) return (TpClient *) client; } + properties = mcd_request_dup_properties (self); sorted_handlers = _mcd_client_registry_list_possible_handlers ( - self->clients, self->preferred_handler, self->properties, + self->clients, self->preferred_handler, properties, NULL, NULL); + g_variant_unref (properties); if (sorted_handlers != NULL) { diff --git a/src/request.h b/src/request.h index f0c0bc4..03a456b 100644 --- a/src/request.h +++ b/src/request.h @@ -63,6 +63,7 @@ G_GNUC_INTERNAL McdRequest *_mcd_request_new (McdClientRegistry *clients, G_GNUC_INTERNAL gboolean _mcd_request_get_use_existing (McdRequest *self); G_GNUC_INTERNAL McdAccount *_mcd_request_get_account (McdRequest *self); G_GNUC_INTERNAL GHashTable *_mcd_request_get_properties (McdRequest *self); +G_GNUC_INTERNAL GVariant *mcd_request_dup_properties (McdRequest *self); G_GNUC_INTERNAL gint64 _mcd_request_get_user_action_time (McdRequest *self); G_GNUC_INTERNAL const gchar *_mcd_request_get_preferred_handler ( McdRequest *self); -- 1.7.10.4