From 8361f74646564000d9fcd297ed4d6dcbaf4cd3d3 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 4 Aug 2015 17:34:11 +0200 Subject: [PATCH] introspect: improve instrospection Pass changed properties around so that we can print them --- src/client/context.c | 20 ++++++--- src/client/introspect.c | 8 ++-- src/client/introspect.h | 4 +- src/client/stream.c | 3 +- src/client/subscribe.c | 40 ++++++++++++----- src/client/subscribe.h | 8 ++-- src/gst/gstpinosdeviceprovider.c | 13 +++--- src/tests/test-subscribe.c | 73 +++++++++++++++++++++----------- 8 files changed, 110 insertions(+), 59 deletions(-) diff --git a/src/client/context.c b/src/client/context.c index 5e3c6bac9..29532c8d6 100644 --- a/src/client/context.c +++ b/src/client/context.c @@ -35,6 +35,7 @@ static void subscription_cb (PinosSubscribe *subscribe, PinosSubscriptionEvent event, PinosSubscriptionFlags flags, GDBusProxy *object, + GStrv properties, gpointer user_data); enum @@ -246,6 +247,8 @@ pinos_context_class_init (PinosContextClass * klass) * @event: A #PinosSubscriptionEvent * @flags: #PinosSubscriptionFlags indicating the object * @object: the GDBusProxy object + * @properties: extra properties that changed or %NULL when all properties + * are affected (new and remove) * * Notify about a new object that was added/removed/modified. */ @@ -257,10 +260,11 @@ pinos_context_class_init (PinosContextClass * klass) NULL, g_cclosure_marshal_generic, G_TYPE_NONE, - 3, + 4, PINOS_TYPE_SUBSCRIPTION_EVENT, PINOS_TYPE_SUBSCRIPTION_FLAGS, - G_TYPE_DBUS_PROXY); + G_TYPE_DBUS_PROXY, + G_TYPE_STRV); } @@ -411,17 +415,18 @@ subscription_cb (PinosSubscribe *subscribe, PinosSubscriptionEvent event, PinosSubscriptionFlags flags, GDBusProxy *object, + GStrv properties, gpointer user_data) { PinosContext *context = user_data; PinosContextPrivate *priv = context->priv; switch (flags) { - case PINOS_SUBSCRIPTION_FLAGS_DAEMON: + case PINOS_SUBSCRIPTION_FLAG_DAEMON: priv->daemon = g_object_ref (object); break; - case PINOS_SUBSCRIPTION_FLAGS_CLIENT: + case PINOS_SUBSCRIPTION_FLAG_CLIENT: if (event == PINOS_SUBSCRIPTION_EVENT_NEW) { priv->clients = g_list_prepend (priv->clients, object); } else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) { @@ -434,14 +439,14 @@ subscription_cb (PinosSubscribe *subscribe, } break; - case PINOS_SUBSCRIPTION_FLAGS_SOURCE: + case PINOS_SUBSCRIPTION_FLAG_SOURCE: if (event == PINOS_SUBSCRIPTION_EVENT_NEW) priv->sources = g_list_prepend (priv->sources, object); else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) priv->sources = g_list_remove (priv->sources, object); break; - case PINOS_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT: + case PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT: if (event == PINOS_SUBSCRIPTION_EVENT_NEW) priv->source_outputs = g_list_prepend (priv->source_outputs, object); else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) @@ -455,7 +460,8 @@ subscription_cb (PinosSubscribe *subscribe, 0, event, flags, - object); + object, + properties); } diff --git a/src/client/introspect.c b/src/client/introspect.c index ab723f890..f23548df1 100644 --- a/src/client/introspect.c +++ b/src/client/introspect.c @@ -227,10 +227,10 @@ source_fill_info (PinosSourceInfo *info, GDBusProxy *proxy) if ((variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "PossibleFormats"))) { gsize len; gchar *formats = g_variant_dup_string (variant, &len); - info->formats = g_bytes_new_take (formats, len + 1); + info->possible_formats = g_bytes_new_take (formats, len + 1); g_variant_unref (variant); } else { - info->formats = NULL; + info->possible_formats = NULL; } } @@ -239,8 +239,8 @@ source_clear_info (PinosSourceInfo *info) { if (info->properties) pinos_properties_free (info->properties); - if (info->formats) - g_bytes_unref (info->formats); + if (info->possible_formats) + g_bytes_unref (info->possible_formats); } /** diff --git a/src/client/introspect.h b/src/client/introspect.h index bec90201f..768191d0b 100644 --- a/src/client/introspect.h +++ b/src/client/introspect.h @@ -124,7 +124,7 @@ typedef enum { * @name: name the source, suitable for display * @properties: the properties of the source * @state: the current state of the source - * @formats: the supported formats + * @possible formats: the possible formats this source can produce * * The source information. Extra information can be added in later * versions. @@ -135,7 +135,7 @@ typedef struct { const char *name; PinosProperties *properties; PinosSourceState state; - GBytes *formats; + GBytes *possible_formats; } PinosSourceInfo; /** diff --git a/src/client/stream.c b/src/client/stream.c index c9864e780..bf9ec7417 100644 --- a/src/client/stream.c +++ b/src/client/stream.c @@ -179,13 +179,14 @@ subscription_cb (PinosSubscribe *subscribe, PinosSubscriptionEvent event, PinosSubscriptionFlags flags, GDBusProxy *object, + GStrv properties, gpointer user_data) { PinosStream *stream = PINOS_STREAM (user_data); PinosStreamPrivate *priv = stream->priv; switch (flags) { - case PINOS_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT: + case PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT: if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) { if (object == priv->source_output) { priv->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, "output disappeared"); diff --git a/src/client/subscribe.c b/src/client/subscribe.c index df854b906..4404c3f56 100644 --- a/src/client/subscribe.c +++ b/src/client/subscribe.c @@ -92,26 +92,27 @@ subscription_set_state (PinosSubscribe *subscribe, static void notify_event (PinosSubscribe *subscribe, PinosObjectData *data, - PinosSubscriptionEvent event) + PinosSubscriptionEvent event, + GStrv properties) { const gchar *interface_name; PinosSubscriptionFlags flags = 0; interface_name = g_dbus_proxy_get_interface_name (data->proxy); if (g_strcmp0 (interface_name, "org.pinos.Daemon1") == 0) { - flags = PINOS_SUBSCRIPTION_FLAGS_DAEMON; + flags = PINOS_SUBSCRIPTION_FLAG_DAEMON; } else if (g_strcmp0 (interface_name, "org.pinos.Client1") == 0) { - flags = PINOS_SUBSCRIPTION_FLAGS_CLIENT; + flags = PINOS_SUBSCRIPTION_FLAG_CLIENT; } else if (g_strcmp0 (interface_name, "org.pinos.Source1") == 0) { - flags = PINOS_SUBSCRIPTION_FLAGS_SOURCE; + flags = PINOS_SUBSCRIPTION_FLAG_SOURCE; } else if (g_strcmp0 (interface_name, "org.pinos.SourceOutput1") == 0) { - flags = PINOS_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT; + flags = PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT; } g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, - event, flags, data->proxy); + event, flags, data->proxy, properties); } static void @@ -121,8 +122,22 @@ on_proxy_properties_changed (GDBusProxy *proxy, gpointer user_data) { PinosObjectData *data = user_data; + GPtrArray *ptr; + GVariantIter iter; + GVariant *value; + gchar *key; - notify_event (data->subscribe, data, PINOS_SUBSCRIPTION_EVENT_CHANGE); + ptr = g_ptr_array_new_with_free_func (g_free); + g_variant_iter_init (&iter, changed_properties); + while (g_variant_iter_loop (&iter, "{sv}", &key, &value)) { + g_ptr_array_add (ptr, g_strdup (key)); + } + g_ptr_array_add (ptr, NULL); + + notify_event (data->subscribe, data, PINOS_SUBSCRIPTION_EVENT_CHANGE, + (gchar **) ptr->pdata); + + g_ptr_array_free (ptr, TRUE); } static void @@ -143,7 +158,7 @@ remove_data (PinosSubscribe *subscribe, if (data->pending) { data->removed = TRUE; } else { - notify_event (subscribe, data, PINOS_SUBSCRIPTION_EVENT_REMOVE); + notify_event (subscribe, data, PINOS_SUBSCRIPTION_EVENT_REMOVE, NULL); object_data_free (data); } } @@ -189,7 +204,7 @@ on_proxy_created (GObject *source_object, (GCallback) on_proxy_properties_changed, data); - notify_event (subscribe, data, PINOS_SUBSCRIPTION_EVENT_NEW); + notify_event (subscribe, data, PINOS_SUBSCRIPTION_EVENT_NEW, NULL); for (walk = data->tasks; walk; walk = g_list_next (walk)) { GTask *task = walk->data; @@ -636,6 +651,8 @@ pinos_subscribe_class_init (PinosSubscribeClass * klass) * @event: A #PinosSubscriptionEvent * @flags: #PinosSubscriptionFlags indicating the object * @id: the unique and opaque object id + * @properties: extra properties that changed or %NULL when all properties + * are affected (new or remove) * * Notify about a new object that was added/removed/modified. */ @@ -647,10 +664,11 @@ pinos_subscribe_class_init (PinosSubscribeClass * klass) NULL, g_cclosure_marshal_generic, G_TYPE_NONE, - 3, + 4, PINOS_TYPE_SUBSCRIPTION_EVENT, PINOS_TYPE_SUBSCRIPTION_FLAGS, - G_TYPE_POINTER); + G_TYPE_POINTER, + G_TYPE_STRV); } static void diff --git a/src/client/subscribe.h b/src/client/subscribe.h index cfaf62dce..8e01a4327 100644 --- a/src/client/subscribe.h +++ b/src/client/subscribe.h @@ -45,10 +45,10 @@ typedef enum { } PinosSubscriptionState; typedef enum { - PINOS_SUBSCRIPTION_FLAGS_DAEMON = (1 << 0), - PINOS_SUBSCRIPTION_FLAGS_CLIENT = (1 << 1), - PINOS_SUBSCRIPTION_FLAGS_SOURCE = (1 << 2), - PINOS_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT = (1 << 3), + PINOS_SUBSCRIPTION_FLAG_DAEMON = (1 << 0), + PINOS_SUBSCRIPTION_FLAG_CLIENT = (1 << 1), + PINOS_SUBSCRIPTION_FLAG_SOURCE = (1 << 2), + PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT = (1 << 3), } PinosSubscriptionFlags; #define PINOS_SUBSCRIPTION_FLAGS_ALL 0xf diff --git a/src/gst/gstpinosdeviceprovider.c b/src/gst/gstpinosdeviceprovider.c index f75edc42b..0956164dc 100644 --- a/src/gst/gstpinosdeviceprovider.c +++ b/src/gst/gstpinosdeviceprovider.c @@ -198,8 +198,8 @@ new_source (const PinosSourceInfo *info) gpointer state = NULL; const gchar *klass; - if (info->formats) - caps = gst_caps_from_string (g_bytes_get_data (info->formats, NULL)); + if (info->possible_formats) + caps = gst_caps_from_string (g_bytes_get_data (info->possible_formats, NULL)); else caps = gst_caps_new_any(); @@ -273,19 +273,20 @@ context_subscribe_cb (PinosContext *context, PinosSubscriptionEvent type, PinosSubscriptionFlags flags, gpointer id, - gpointer user_data) + gpointer user_data, + GStrv properties) { GstPinosDeviceProvider *self = user_data; GstDeviceProvider *provider = user_data; GstPinosDevice *dev; - if (flags != PINOS_SUBSCRIPTION_FLAGS_SOURCE) + if (flags != PINOS_SUBSCRIPTION_FLAG_SOURCE) return; dev = find_device (provider, id); if (type == PINOS_SUBSCRIPTION_EVENT_NEW) { - if (flags == PINOS_SUBSCRIPTION_FLAGS_SOURCE && dev == NULL) + if (flags == PINOS_SUBSCRIPTION_FLAG_SOURCE && dev == NULL) pinos_context_get_source_info_by_id (context, id, PINOS_SOURCE_INFO_FLAGS_FORMATS, @@ -293,7 +294,7 @@ context_subscribe_cb (PinosContext *context, NULL, self); } else if (type == PINOS_SUBSCRIPTION_EVENT_REMOVE) { - if (flags == PINOS_SUBSCRIPTION_FLAGS_SOURCE && dev != NULL) { + if (flags == PINOS_SUBSCRIPTION_FLAG_SOURCE && dev != NULL) { gst_device_provider_device_remove (GST_DEVICE_PROVIDER (self), GST_DEVICE (dev)); } diff --git a/src/tests/test-subscribe.c b/src/tests/test-subscribe.c index 0f6721f80..125060809 100644 --- a/src/tests/test-subscribe.c +++ b/src/tests/test-subscribe.c @@ -83,6 +83,8 @@ print_properties (PinosProperties *props) static gboolean dump_daemon_info (PinosContext *c, const PinosDaemonInfo *info, gpointer userdata) { + const gchar * const *props = userdata; + if (info == NULL) return FALSE; @@ -92,7 +94,8 @@ dump_daemon_info (PinosContext *c, const PinosDaemonInfo *info, gpointer userdat g_print ("\tversion: \"%s\"\n", info->version); g_print ("\tname: \"%s\"\n", info->name); g_print ("\tcookie: %d\n", info->cookie); - print_properties (info->properties); + if (!props || g_strv_contains (props, "Properties")) + print_properties (info->properties); return TRUE; } @@ -100,12 +103,16 @@ dump_daemon_info (PinosContext *c, const PinosDaemonInfo *info, gpointer userdat static gboolean dump_client_info (PinosContext *c, const PinosClientInfo *info, gpointer userdata) { + const gchar * const *props = userdata; + if (info == NULL) return FALSE; g_print ("\tid: %p\n", info->id); - g_print ("\tname: \"%s\"\n", info->name); - print_properties (info->properties); + if (!props || g_strv_contains (props, "Name")) + g_print ("\tname: \"%s\"\n", info->name); + if (!props || g_strv_contains (props, "Properties")) + print_properties (info->properties); return TRUE; } @@ -113,15 +120,22 @@ dump_client_info (PinosContext *c, const PinosClientInfo *info, gpointer userdat static gboolean dump_source_info (PinosContext *c, const PinosSourceInfo *info, gpointer userdata) { + const gchar * const *props = userdata; + if (info == NULL) return FALSE; g_print ("\tid: %p\n", info->id); - g_print ("\tsource-path: \"%s\"\n", info->source_path); - g_print ("\tname: \"%s\"\n", info->name); - g_print ("\tstate: %d\n", info->state); - print_formats ("formats", info->formats); - print_properties (info->properties); + if (!props || g_strv_contains (props, "Source")) + g_print ("\tsource-path: \"%s\"\n", info->source_path); + if (!props || g_strv_contains (props, "Name")) + g_print ("\tname: \"%s\"\n", info->name); + if (!props || g_strv_contains (props, "State")) + g_print ("\tstate: %d\n", info->state); + if (!props || g_strv_contains (props, "PossibleFormats")) + print_formats ("possible formats", info->possible_formats); + if (!props || g_strv_contains (props, "Properties")) + print_properties (info->properties); return TRUE; } @@ -129,53 +143,62 @@ dump_source_info (PinosContext *c, const PinosSourceInfo *info, gpointer userdat static gboolean dump_source_output_info (PinosContext *c, const PinosSourceOutputInfo *info, gpointer userdata) { + const gchar * const *props = userdata; + if (info == NULL) return FALSE; g_print ("\tid: %p\n", info->id); - g_print ("\tclient-path: \"%s\"\n", info->client_path); - g_print ("\tsource-path: \"%s\"\n", info->source_path); - print_formats ("possible-formats", info->possible_formats); - g_print ("\tstate: \"%d\"\n", info->state); - print_formats ("format", info->format); - print_properties (info->properties); + if (!props || g_strv_contains (props, "Client")) + g_print ("\tclient-path: \"%s\"\n", info->client_path); + if (!props || g_strv_contains (props, "Source")) + g_print ("\tsource-path: \"%s\"\n", info->source_path); + if (!props || g_strv_contains (props, "PossibleFormats")) + print_formats ("possible-formats", info->possible_formats); + if (!props || g_strv_contains (props, "State")) + g_print ("\tstate: \"%d\"\n", info->state); + if (!props || g_strv_contains (props, "Format")) + print_formats ("format", info->format); + if (!props || g_strv_contains (props, "Properties")) + print_properties (info->properties); return TRUE; } static void -dump_object (PinosContext *context, GDBusProxy *proxy, PinosSubscriptionFlags flags) +dump_object (PinosContext *context, GDBusProxy *proxy, PinosSubscriptionFlags flags, + GStrv properties) { - if (flags & PINOS_SUBSCRIPTION_FLAGS_DAEMON) { + if (flags & PINOS_SUBSCRIPTION_FLAG_DAEMON) { pinos_context_get_daemon_info (context, PINOS_DAEMON_INFO_FLAGS_NONE, dump_daemon_info, NULL, - NULL); + properties); } - else if (flags & PINOS_SUBSCRIPTION_FLAGS_CLIENT) { + else if (flags & PINOS_SUBSCRIPTION_FLAG_CLIENT) { pinos_context_get_client_info_by_id (context, proxy, PINOS_CLIENT_INFO_FLAGS_NONE, dump_client_info, NULL, - NULL); + properties); } - else if (flags & PINOS_SUBSCRIPTION_FLAGS_SOURCE) { + else if (flags & PINOS_SUBSCRIPTION_FLAG_SOURCE) { pinos_context_get_source_info_by_id (context, proxy, PINOS_SOURCE_INFO_FLAGS_FORMATS, dump_source_info, NULL, - NULL); + properties); } - else if (flags & PINOS_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT) { + else if (flags & PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT) { pinos_context_get_source_output_info_by_id (context, proxy, PINOS_SOURCE_OUTPUT_INFO_FLAGS_NONE, dump_source_output_info, NULL, - NULL); + properties); } } @@ -184,16 +207,18 @@ subscription_cb (PinosContext *context, PinosSubscriptionEvent type, PinosSubscriptionFlags flags, gpointer id, + GStrv properties, gpointer user_data) { switch (type) { case PINOS_SUBSCRIPTION_EVENT_NEW: g_print ("added: %s\n", g_dbus_proxy_get_object_path (id)); - dump_object (context, G_DBUS_PROXY (id), flags); + dump_object (context, G_DBUS_PROXY (id), flags, properties); break; case PINOS_SUBSCRIPTION_EVENT_CHANGE: g_print ("changed: %s\n", g_dbus_proxy_get_object_path (id)); + dump_object (context, G_DBUS_PROXY (id), flags, properties); break; case PINOS_SUBSCRIPTION_EVENT_REMOVE: