From 9dac5fdaf51535000ebc20006a3219415c1592ec Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Thu, 5 Dec 2019 10:46:34 -0500 Subject: [PATCH 1/3] parser-streams: add get_lowest_stream API --- modules/module-config-policy/parser-streams.c | 15 +++++++++++++++ modules/module-config-policy/parser-streams.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/modules/module-config-policy/parser-streams.c b/modules/module-config-policy/parser-streams.c index 46e7caf3..b1c718aa 100644 --- a/modules/module-config-policy/parser-streams.c +++ b/modules/module-config-policy/parser-streams.c @@ -31,6 +31,21 @@ wp_parser_streams_find_stream (const struct WpParserStreamsData *data, return NULL; } +const struct WpParserStreamsStreamData * +wp_parser_streams_get_lowest_stream (const struct WpParserStreamsData *data) +{ + const struct WpParserStreamsStreamData *res = NULL; + guint lowest = G_MAXUINT; + for (guint i = 0; i < data->n_streams; i++) { + const struct WpParserStreamsStreamData *s = data->streams + i; + if (s->priority < lowest) { + lowest = s->priority; + res = s; + } + } + return res; +} + static void wp_parser_streams_config_parser_init (gpointer iface, gpointer iface_data); diff --git a/modules/module-config-policy/parser-streams.h b/modules/module-config-policy/parser-streams.h index 79dba324..75c6209b 100644 --- a/modules/module-config-policy/parser-streams.h +++ b/modules/module-config-policy/parser-streams.h @@ -32,6 +32,8 @@ struct WpParserStreamsData { /* Helpers */ const struct WpParserStreamsStreamData *wp_parser_streams_find_stream ( const struct WpParserStreamsData *data, const char *name); +const struct WpParserStreamsStreamData *wp_parser_streams_get_lowest_stream ( + const struct WpParserStreamsData *data); #define WP_TYPE_PARSER_STREAMS (wp_parser_streams_get_type ()) G_DECLARE_FINAL_TYPE (WpParserStreams, wp_parser_streams, -- GitLab From 34ebbe47d7fcba6bbb69746c1a29d69c136db970 Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Thu, 5 Dec 2019 10:50:10 -0500 Subject: [PATCH 2/3] config-policy: prioritize role from configuration file The role defined in the endpoint-link configuration files must have higher priority than the one set in the endpoint. If none of them are set, the config policy fallbacks to the lowest one defined in the streams configuration file --- modules/module-config-policy/config-policy.c | 44 +++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/modules/module-config-policy/config-policy.c b/modules/module-config-policy/config-policy.c index 2158dbfa..d6bad7f0 100644 --- a/modules/module-config-policy/config-policy.c +++ b/modules/module-config-policy/config-policy.c @@ -246,6 +246,34 @@ wp_config_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep) WP_STREAM_ID_NONE, target, stream_id, data); } +static const char * +wp_config_policy_get_prioritized_stream (WpPolicy *policy, + const char *ep_stream, const char *te_stream, const char *te_streams) +{ + WpConfigPolicy *self = WP_CONFIG_POLICY (policy); + + /* The target stream has higher priority than the endpoint stream */ + const char *res = te_stream ? te_stream : ep_stream; + if (res) + return res; + + /* If both streams are null, and no streams file is defined, return NULL */ + if (!te_streams) + return NULL; + + /* Otherwise get the lowest stream from streams */ + g_autoptr (WpConfigParser) parser = NULL; + const struct WpParserStreamsData *streams = NULL; + const struct WpParserStreamsStreamData *lowest = NULL; + parser = wp_configuration_get_parser (self->config, + WP_PARSER_STREAMS_EXTENSION); + streams = wp_config_parser_get_matched_data (parser, (gpointer)te_streams); + if (!streams) + return NULL; + lowest = wp_parser_streams_get_lowest_stream (streams); + return lowest ? lowest->name : NULL; +} + static WpEndpoint * wp_config_policy_find_endpoint (WpPolicy *policy, GVariant *props, guint32 *stream_id) @@ -258,7 +286,7 @@ wp_config_policy_find_endpoint (WpPolicy *policy, GVariant *props, WpEndpoint *target = NULL; g_autoptr (WpProxy) proxy = NULL; g_autoptr (WpProperties) p = NULL; - const char *role = NULL, *target_role = NULL; + const char *role = NULL; /* Get the data from props */ g_variant_lookup (props, "data", "t", &data); @@ -287,11 +315,15 @@ wp_config_policy_find_endpoint (WpPolicy *policy, GVariant *props, /* Set the stream id */ if (stream_id) { - g_variant_lookup (props, "role", "&s", &role); - target_role = role ? role : data->te.stream; - *stream_id = target && target_role ? - wp_endpoint_find_stream (target, target_role) : - WP_CONTROL_ID_NONE; + if (target) { + g_variant_lookup (props, "role", "&s", &role); + const char *prioritized = wp_config_policy_get_prioritized_stream (policy, + role, data->te.stream, data->te.streams); + *stream_id = prioritized ? wp_endpoint_find_stream (target, prioritized) : + WP_STREAM_ID_NONE; + } else { + *stream_id = WP_STREAM_ID_NONE; + } } return g_object_ref (target); -- GitLab From 8bdadd5a71510afce3254976605a2860fedc2a0b Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Thu, 5 Dec 2019 10:51:39 -0500 Subject: [PATCH 3/3] tests: fix config policy role test to work with new priotity logic --- tests/modules/config-policy.c | 49 +++++++++++++------ .../config-playback-role/3.streams | 7 +++ ...ink => stream-output-fake-1.endpoint-link} | 1 + .../stream-output-fake-2.endpoint-link | 10 ++++ .../stream-output-fake-3.endpoint-link | 11 +++++ 5 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 tests/modules/config-policy/config-playback-role/3.streams rename tests/modules/config-policy/config-playback-role/{stream-output-fake.endpoint-link => stream-output-fake-1.endpoint-link} (92%) create mode 100644 tests/modules/config-policy/config-playback-role/stream-output-fake-2.endpoint-link create mode 100644 tests/modules/config-policy/config-playback-role/stream-output-fake-3.endpoint-link diff --git a/tests/modules/config-policy.c b/tests/modules/config-policy.c index 5d6692c5..9a1a9dd8 100644 --- a/tests/modules/config-policy.c +++ b/tests/modules/config-policy.c @@ -370,48 +370,69 @@ playback_role (TestConfigPolicyFixture *f, gconstpointer data) g_autoptr (WpEndpointLink) link = NULL; g_autoptr (WpEndpoint) src = NULL; g_autoptr (WpEndpoint) sink = NULL; + g_autoptr (WpEndpoint) dev = NULL; g_autoptr (WpEndpoint) ep1 = NULL; g_autoptr (WpEndpoint) ep2 = NULL; g_autoptr (WpEndpoint) ep3 = NULL; /* Create the device with 2 roles: "0" with id 0, and "1" with id 1 */ - ep1 = wp_config_policy_context_add_endpoint (ctx, "ep1", "Fake/Sink", + dev = wp_config_policy_context_add_endpoint (ctx, "dev", "Fake/Sink", PW_DIRECTION_INPUT, NULL, NULL, 2, &link); - g_assert_nonnull (ep1); + g_assert_nonnull (dev); g_assert_null (link); - g_assert_false (wp_endpoint_is_linked (ep1)); + g_assert_false (wp_endpoint_is_linked (dev)); - /* Create the first client endpoint with role "0" and make sure it has - * priority over the one defined in the configuration file which is "1" */ - ep2 = wp_config_policy_context_add_endpoint (ctx, "ep2", "Stream/Output/Fake", + /* Create the first client endpoint with role "0" and make sure the role + * defined in the configuration file which is "1" is used */ + ep1 = wp_config_policy_context_add_endpoint (ctx, "ep1", "Stream/Output/Fake", PW_DIRECTION_OUTPUT, NULL, "0", 0, &link); + g_assert_nonnull (ep1); + g_assert_nonnull (link); + g_assert_true (wp_endpoint_is_linked (ep1)); + g_assert_true (wp_endpoint_is_linked (dev)); + src = wp_endpoint_link_get_source_endpoint (link); + sink = wp_endpoint_link_get_sink_endpoint (link); + g_assert_true (ep1 == src); + g_assert_true (dev == sink); + g_assert_true ( + WP_STREAM_ID_NONE == wp_endpoint_link_get_source_stream (link)); + g_assert_true (1 == wp_endpoint_link_get_sink_stream (link)); + wp_config_policy_context_remove_endpoint (ctx, ep1); + + /* Create the second client endpoint with role "1" and make sure it uses it + * because there is none defined in the configuration file */ + ep2 = wp_config_policy_context_add_endpoint (ctx, "ep2", "Stream/Output/Fake", + PW_DIRECTION_OUTPUT, NULL, "1", 0, &link); g_assert_nonnull (ep2); g_assert_nonnull (link); g_assert_true (wp_endpoint_is_linked (ep2)); - g_assert_true (wp_endpoint_is_linked (ep1)); + g_assert_true (wp_endpoint_is_linked (dev)); src = wp_endpoint_link_get_source_endpoint (link); sink = wp_endpoint_link_get_sink_endpoint (link); g_assert_true (ep2 == src); - g_assert_true (ep1 == sink); + g_assert_true (dev == sink); g_assert_true ( WP_STREAM_ID_NONE == wp_endpoint_link_get_source_stream (link)); - g_assert_true (0 == wp_endpoint_link_get_sink_stream (link)); + g_assert_true (1 == wp_endpoint_link_get_sink_stream (link)); + wp_config_policy_context_remove_endpoint (ctx, ep2); - /* Create the second client endpoint without role and make sure it uses - * the one defined in the configuration file which is "1" */ + /* Create the third client endpoint without role and make sure it uses the + * lowest priority on from the streams file because the endpoint-link file + * does not have any either */ ep3 = wp_config_policy_context_add_endpoint (ctx, "ep3", "Stream/Output/Fake", PW_DIRECTION_OUTPUT, NULL, NULL, 0, &link); g_assert_nonnull (ep3); g_assert_nonnull (link); g_assert_true (wp_endpoint_is_linked (ep3)); - g_assert_true (wp_endpoint_is_linked (ep1)); + g_assert_true (wp_endpoint_is_linked (dev)); src = wp_endpoint_link_get_source_endpoint (link); sink = wp_endpoint_link_get_sink_endpoint (link); g_assert_true (ep3 == src); - g_assert_true (ep1 == sink); + g_assert_true (dev == sink); g_assert_true ( WP_STREAM_ID_NONE == wp_endpoint_link_get_source_stream (link)); - g_assert_true (1 == wp_endpoint_link_get_sink_stream (link)); + g_assert_true (0 == wp_endpoint_link_get_sink_stream (link)); + wp_config_policy_context_remove_endpoint (ctx, ep3); } int diff --git a/tests/modules/config-policy/config-playback-role/3.streams b/tests/modules/config-policy/config-playback-role/3.streams new file mode 100644 index 00000000..ce5d0317 --- /dev/null +++ b/tests/modules/config-policy/config-playback-role/3.streams @@ -0,0 +1,7 @@ +[[streams]] +name = "0" +priority = 0 + +[[streams]] +name = "1" +priority = 1 diff --git a/tests/modules/config-policy/config-playback-role/stream-output-fake.endpoint-link b/tests/modules/config-policy/config-playback-role/stream-output-fake-1.endpoint-link similarity index 92% rename from tests/modules/config-policy/config-playback-role/stream-output-fake.endpoint-link rename to tests/modules/config-policy/config-playback-role/stream-output-fake-1.endpoint-link index 2cf9f57f..f323aec6 100644 --- a/tests/modules/config-policy/config-playback-role/stream-output-fake.endpoint-link +++ b/tests/modules/config-policy/config-playback-role/stream-output-fake-1.endpoint-link @@ -1,4 +1,5 @@ [match-endpoint] +name = "ep1" direction = "output" media_class = "Stream/Output/Fake" diff --git a/tests/modules/config-policy/config-playback-role/stream-output-fake-2.endpoint-link b/tests/modules/config-policy/config-playback-role/stream-output-fake-2.endpoint-link new file mode 100644 index 00000000..2482472b --- /dev/null +++ b/tests/modules/config-policy/config-playback-role/stream-output-fake-2.endpoint-link @@ -0,0 +1,10 @@ +[match-endpoint] +name = "ep2" +direction = "output" +media_class = "Stream/Output/Fake" + +[target-endpoint] +media_class = "Fake/Sink" + +[endpoint-link] +keep = false diff --git a/tests/modules/config-policy/config-playback-role/stream-output-fake-3.endpoint-link b/tests/modules/config-policy/config-playback-role/stream-output-fake-3.endpoint-link new file mode 100644 index 00000000..ccdcf8b9 --- /dev/null +++ b/tests/modules/config-policy/config-playback-role/stream-output-fake-3.endpoint-link @@ -0,0 +1,11 @@ +[match-endpoint] +name = "ep3" +direction = "output" +media_class = "Stream/Output/Fake" + +[target-endpoint] +media_class = "Fake/Sink" +streams = "3.streams" + +[endpoint-link] +keep = false -- GitLab