simple-policy: delay unhandled enpoints if target is not found
This commit is contained in:
@@ -20,6 +20,7 @@ struct _WpSimplePolicy
|
|||||||
guint32 selected_ctl_id[2];
|
guint32 selected_ctl_id[2];
|
||||||
gchar *default_playback;
|
gchar *default_playback;
|
||||||
gchar *default_capture;
|
gchar *default_capture;
|
||||||
|
GQueue *unhandled_endpoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (WpSimplePolicy, simple_policy, WP, SIMPLE_POLICY, WpPolicy)
|
G_DECLARE_FINAL_TYPE (WpSimplePolicy, simple_policy, WP, SIMPLE_POLICY, WpPolicy)
|
||||||
@@ -28,6 +29,7 @@ G_DEFINE_TYPE (WpSimplePolicy, simple_policy, WP_TYPE_POLICY)
|
|||||||
static void
|
static void
|
||||||
simple_policy_init (WpSimplePolicy *self)
|
simple_policy_init (WpSimplePolicy *self)
|
||||||
{
|
{
|
||||||
|
self->unhandled_endpoints = g_queue_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -37,6 +39,7 @@ simple_policy_finalize (GObject *object)
|
|||||||
|
|
||||||
g_free (self->default_playback);
|
g_free (self->default_playback);
|
||||||
g_free (self->default_capture);
|
g_free (self->default_capture);
|
||||||
|
g_queue_free_full (self->unhandled_endpoints, (GDestroyNotify)g_object_unref);
|
||||||
|
|
||||||
G_OBJECT_CLASS (simple_policy_parent_class)->finalize (object);
|
G_OBJECT_CLASS (simple_policy_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -249,9 +252,9 @@ on_endpoint_link_created(GObject *initable, GAsyncResult *res, gpointer d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep)
|
handle_client (WpPolicy *policy, WpEndpoint *ep)
|
||||||
{
|
{
|
||||||
const char *media_class = NULL;
|
const char *media_class = wp_endpoint_get_media_class(ep);
|
||||||
GVariantDict d;
|
GVariantDict d;
|
||||||
g_autoptr (WpCore) core = NULL;
|
g_autoptr (WpCore) core = NULL;
|
||||||
g_autoptr (WpEndpoint) target = NULL;
|
g_autoptr (WpEndpoint) target = NULL;
|
||||||
@@ -259,12 +262,6 @@ simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep)
|
|||||||
gboolean is_sink = FALSE;
|
gboolean is_sink = FALSE;
|
||||||
g_autofree gchar *role = NULL;
|
g_autofree gchar *role = NULL;
|
||||||
|
|
||||||
/* TODO: For now we only accept audio stream clients */
|
|
||||||
media_class = wp_endpoint_get_media_class(ep);
|
|
||||||
if (!g_str_has_prefix (media_class, "Stream") ||
|
|
||||||
!g_str_has_suffix (media_class, "Audio"))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Detect if the client is a sink or a source */
|
/* Detect if the client is a sink or a source */
|
||||||
is_sink = g_str_has_prefix (media_class, "Stream/Input");
|
is_sink = g_str_has_prefix (media_class, "Stream/Input");
|
||||||
|
|
||||||
@@ -282,11 +279,8 @@ simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep)
|
|||||||
|
|
||||||
core = wp_policy_get_core (policy);
|
core = wp_policy_get_core (policy);
|
||||||
target = wp_policy_find_endpoint (core, g_variant_dict_end (&d), &stream_id);
|
target = wp_policy_find_endpoint (core, g_variant_dict_end (&d), &stream_id);
|
||||||
if (!target) {
|
if (!target)
|
||||||
g_warning ("Could not find a target endpoint\n");
|
|
||||||
/* TODO: we should kill the client, otherwise it's going to hang waiting */
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlink the target if it is already linked */
|
/* Unlink the target if it is already linked */
|
||||||
if (wp_endpoint_is_linked (target))
|
if (wp_endpoint_is_linked (target))
|
||||||
@@ -304,6 +298,54 @@ simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
try_unhandled_clients (WpPolicy *policy)
|
||||||
|
{
|
||||||
|
WpSimplePolicy *self = WP_SIMPLE_POLICY (policy);
|
||||||
|
WpEndpoint *ep = NULL;
|
||||||
|
GQueue *tmp = g_queue_new ();
|
||||||
|
|
||||||
|
/* Try to handle all the unhandled endpoints, and add them into a tmp queue
|
||||||
|
* if they were not handled */
|
||||||
|
while ((ep = g_queue_pop_head (self->unhandled_endpoints))) {
|
||||||
|
if (handle_client (policy, ep))
|
||||||
|
g_object_unref (ep);
|
||||||
|
else
|
||||||
|
g_queue_push_tail (tmp, ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add back the unhandled endpoints to the unhandled queue */
|
||||||
|
while ((ep = g_queue_pop_head (tmp)))
|
||||||
|
g_queue_push_tail (self->unhandled_endpoints, ep);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
g_queue_free_full (tmp, (GDestroyNotify)g_object_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep)
|
||||||
|
{
|
||||||
|
WpSimplePolicy *self = WP_SIMPLE_POLICY (policy);
|
||||||
|
const char *media_class = NULL;
|
||||||
|
|
||||||
|
/* TODO: For now we only accept audio stream clients */
|
||||||
|
media_class = wp_endpoint_get_media_class(ep);
|
||||||
|
if (!g_str_has_prefix (media_class, "Stream") ||
|
||||||
|
!g_str_has_suffix (media_class, "Audio")) {
|
||||||
|
/* Try handling unhandled endpoints if a non client one has been added */
|
||||||
|
try_unhandled_clients (policy);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle the endpoint */
|
||||||
|
if (handle_client (policy, ep))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Otherwise add it to the unhandled queue */
|
||||||
|
g_queue_push_tail (self->unhandled_endpoints, g_object_ref (ep));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static WpEndpoint *
|
static WpEndpoint *
|
||||||
simple_policy_find_endpoint (WpPolicy *policy, GVariant *props,
|
simple_policy_find_endpoint (WpPolicy *policy, GVariant *props,
|
||||||
guint32 *stream_id)
|
guint32 *stream_id)
|
||||||
|
Reference in New Issue
Block a user