session: fix the default-endpoint prop

* Use a direction instead of a string prop id
* Emit default-endpoint-changed again
* Get rid of the useless virtual methods
This commit is contained in:
George Kiagiadakis 2020-05-25 18:51:23 +03:00
parent 8a94937b2a
commit 162c1d4574
6 changed files with 108 additions and 94 deletions

View file

@ -64,9 +64,26 @@ struct _WpSessionPrivate
G_DEFINE_TYPE_WITH_PRIVATE (WpSession, wp_session, WP_TYPE_PROXY)
static void
wp_session_prop_changed (WpSession * self, const gchar * prop, gpointer data)
{
if (g_strcmp0 (prop, "Wp:defaultSink") == 0) {
g_signal_emit (self, signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED], 0,
WP_DIRECTION_INPUT,
wp_session_get_default_endpoint (self, WP_DIRECTION_INPUT));
}
else if (g_strcmp0 (prop, "Wp:defaultSource") == 0) {
g_signal_emit (self, signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED], 0,
WP_DIRECTION_OUTPUT,
wp_session_get_default_endpoint (self, WP_DIRECTION_OUTPUT));
}
}
static void
wp_session_init (WpSession * self)
{
g_signal_connect (self, "prop-changed",
G_CALLBACK (wp_session_prop_changed), NULL);
}
static void
@ -293,24 +310,6 @@ wp_session_augment (WpProxy * proxy, WpProxyFeatures features)
}
}
static guint32
get_default_endpoint (WpSession * self, const gchar * id_name)
{
g_autoptr (WpSpaPod) pod = wp_proxy_get_prop (WP_PROXY (self), id_name);
gint32 value;
if (pod && wp_spa_pod_get_int (pod, &value))
return (guint32) value;
return 0;
}
static void
set_default_endpoint (WpSession * self, const gchar * id_name, guint32 id)
{
g_autoptr (WpSpaPod) param = wp_spa_pod_new_int (id);
wp_proxy_set_prop (WP_PROXY (self), id_name, param);
}
static void
wp_session_class_init (WpSessionClass * klass)
{
@ -333,23 +332,20 @@ wp_session_class_init (WpSessionClass * klass)
proxy_class->pw_proxy_created = wp_session_pw_proxy_created;
proxy_class->bound = wp_session_bound;
klass->get_default_endpoint = get_default_endpoint;
klass->set_default_endpoint = set_default_endpoint;
/**
* WpSession::default-endpoint-changed:
* @self: the session
* @type: the endpoint type
* @direction: the endpoint direction
* @id: the endpoint's bound id
*
* Emitted when the default endpoint of a specific type changes.
* Emitted when the default endpoint of a specific direction changes.
* The passed @id is the bound id (wp_proxy_get_bound_id()) of the new
* default endpoint.
*/
signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED] = g_signal_new (
"default-endpoint-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 2,
G_TYPE_STRING, G_TYPE_UINT);
WP_TYPE_DIRECTION, G_TYPE_UINT);
/**
* WpSession::endpoints-changed:
@ -394,37 +390,69 @@ wp_session_get_name (WpSession * self)
/**
* wp_session_get_default_endpoint:
* @self: the session
* @id_name: the endpoint id name
* @direction: the endpoint direction
*
* Returns: the bound id of the default endpoint of this @type
* Returns: the bound id of the default endpoint of this @direction
*/
guint32
wp_session_get_default_endpoint (WpSession * self,
const gchar * id_name)
wp_session_get_default_endpoint (WpSession * self, WpDirection direction)
{
g_return_val_if_fail (WP_IS_SESSION (self), SPA_ID_INVALID);
g_return_val_if_fail (WP_SESSION_GET_CLASS (self)->get_default_endpoint,
SPA_ID_INVALID);
g_autoptr (WpSpaPod) pod = NULL;
const gchar *id_name = NULL;
gint32 value;
return WP_SESSION_GET_CLASS (self)->get_default_endpoint (self, id_name);
g_return_val_if_fail (WP_IS_SESSION (self), SPA_ID_INVALID);
switch (direction) {
case WP_DIRECTION_INPUT:
id_name = "Wp:defaultSink";
break;
case WP_DIRECTION_OUTPUT:
id_name = "Wp:defaultSource";
break;
default:
g_return_val_if_reached (SPA_ID_INVALID);
break;
}
pod = wp_proxy_get_prop (WP_PROXY (self), id_name);
if (pod && wp_spa_pod_get_int (pod, &value))
return (guint32) value;
return 0;
}
/**
* wp_session_set_default_endpoint:
* @self: the session
* @id_name: the endpoint id name
* @id: the bound id of the endpoint to set as the default for this @type
* @direction: the endpoint direction
* @id: the bound id of the endpoint to set as the default for this @direction
*
* Sets the default endpoint for this @type to be the one identified with @id
* Sets the default endpoint for this @direction to be the one identified
* with @id
*/
void
wp_session_set_default_endpoint (WpSession * self, const char * id_name,
wp_session_set_default_endpoint (WpSession * self, WpDirection direction,
guint32 id)
{
g_return_if_fail (WP_IS_SESSION (self));
g_return_if_fail (WP_SESSION_GET_CLASS (self)->set_default_endpoint);
g_autoptr (WpSpaPod) pod = NULL;
const gchar *id_name = NULL;
WP_SESSION_GET_CLASS (self)->set_default_endpoint (self, id_name, id);
g_return_if_fail (WP_IS_SESSION (self));
switch (direction) {
case WP_DIRECTION_INPUT:
id_name = "Wp:defaultSink";
break;
case WP_DIRECTION_OUTPUT:
id_name = "Wp:defaultSource";
break;
default:
g_return_if_reached ();
break;
}
pod = wp_spa_pod_new_int (id);
wp_proxy_set_prop (WP_PROXY (self), id_name, pod);
}
/**

View file

@ -55,10 +55,6 @@ G_DECLARE_DERIVABLE_TYPE (WpSession, wp_session, WP, SESSION, WpProxy)
struct _WpSessionClass
{
WpProxyClass parent_class;
guint32 (*get_default_endpoint) (WpSession * self, const gchar * id_name);
void (*set_default_endpoint) (WpSession * self, const gchar * id_name,
guint32 id);
};
WP_API
@ -66,11 +62,11 @@ const gchar * wp_session_get_name (WpSession * self);
WP_API
guint32 wp_session_get_default_endpoint (WpSession * self,
const gchar * id_name);
WpDirection direction);
WP_API
void wp_session_set_default_endpoint (WpSession * self, const gchar * id_name,
guint32 id);
void wp_session_set_default_endpoint (WpSession * self,
WpDirection direction, guint32 id);
/* endpoints */

View file

@ -103,17 +103,8 @@ wp_config_policy_context_get_endpoint_target (WpConfigPolicyContext *self,
/* Otherwise, use the default session endpoint */
else {
guint def_id = 0;
switch (data->me.endpoint_data.direction) {
case WP_DIRECTION_INPUT:
def_id = wp_session_get_default_endpoint (session, "Wp:defaultSource");
break;
case WP_DIRECTION_OUTPUT:
def_id = wp_session_get_default_endpoint (session, "Wp:defaultSink");
break;
default:
g_return_val_if_reached (NULL);
}
guint def_id = wp_session_get_default_endpoint (session,
data->me.endpoint_data.direction);
target = wp_session_lookup_endpoint (session,
WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", def_id, NULL);
}

View file

@ -18,6 +18,9 @@
G_DEFINE_QUARK (wp-session-settings-sink-file, session_settings_sink_file)
G_DEFINE_QUARK (wp-session-settings-source-file, session_settings_source_file)
#define direction_to_dbg_string(dir) \
((dir == WP_DIRECTION_INPUT) ? "sink" : "source")
struct _WpSessionSettings
{
WpPlugin parent;
@ -51,7 +54,7 @@ wp_session_settings_finalize (GObject * object)
}
static void
on_default_endpoint_changed (WpSession * session, const gchar * type,
on_default_endpoint_changed (WpSession * session, WpDirection dir,
guint32 id, WpSessionSettings * self)
{
GFile *file = NULL;
@ -59,22 +62,20 @@ on_default_endpoint_changed (WpSession * session, const gchar * type,
g_autoptr (GError) error = NULL;
g_autoptr (WpEndpoint) ep = NULL;
wp_debug_object (self, "%s on " WP_OBJECT_FORMAT " changed (%u), storing",
type, WP_OBJECT_ARGS (session), id);
wp_debug_object (self, "default %s on " WP_OBJECT_FORMAT " changed (%u), "
"storing", direction_to_dbg_string (dir), WP_OBJECT_ARGS (session), id);
if (g_strcmp0 (type, "Wp:defaultSink") == 0)
file = g_object_get_qdata (G_OBJECT (session),
session_settings_sink_file_quark ());
else if (g_strcmp0 (type, "Wp:defaultSource") == 0)
file = g_object_get_qdata (G_OBJECT (session),
file = g_object_get_qdata (G_OBJECT (session),
(dir == WP_DIRECTION_INPUT) ?
session_settings_sink_file_quark () :
session_settings_source_file_quark ());
g_return_if_fail (file);
ep = wp_session_lookup_endpoint (session,
WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", id, NULL);
if (!ep) {
wp_warning_object (self, "%s (%u) on " WP_OBJECT_FORMAT " not found",
type, id, WP_OBJECT_ARGS (session));
wp_warning_object (self, "default %s (%u) on " WP_OBJECT_FORMAT " not found",
direction_to_dbg_string (dir), id, WP_OBJECT_ARGS (session));
return;
}
@ -166,14 +167,12 @@ reevaluate_defaults (WpSessionSettings * self,
id = find_highest_prio (session, dir);
wp_debug_object (self, "selecting default %s for " WP_OBJECT_FORMAT ": %u",
(dir == WP_DIRECTION_INPUT) ? "sink" : "source",
WP_OBJECT_ARGS (session), id);
direction_to_dbg_string (dir), WP_OBJECT_ARGS (session), id);
/* block the signal to avoid storing this on the file;
only selections done by the user should be stored */
g_signal_handlers_block_by_func (session, on_default_endpoint_changed, self);
wp_session_set_default_endpoint (session,
(dir == WP_DIRECTION_INPUT) ? "Wp:defaultSink" : "Wp:defaultSource", id);
wp_session_set_default_endpoint (session, dir, id);
g_signal_handlers_unblock_by_func (session, on_default_endpoint_changed, self);
}

View file

@ -170,9 +170,9 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
session = wp_impl_session_new (fixture->base.core);
wp_impl_session_set_property (session, "test.property", "test-value");
wp_session_set_default_endpoint (WP_SESSION (session),
"Wp:defaultSink", 5);
WP_DIRECTION_INPUT, 5);
wp_session_set_default_endpoint (WP_SESSION (session),
"Wp:defaultSource", 9);
WP_DIRECTION_OUTPUT, 9);
/* verify properties are set before export */
{
@ -182,9 +182,9 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
"test-value");
}
g_assert_cmpuint (wp_session_get_default_endpoint (WP_SESSION (session),
"Wp:defaultSink"), ==, 5);
WP_DIRECTION_INPUT), ==, 5);
g_assert_cmpuint (wp_session_get_default_endpoint (WP_SESSION (session),
"Wp:defaultSource"), ==, 9);
WP_DIRECTION_OUTPUT), ==, 9);
/* do export */
wp_proxy_augment (WP_PROXY (session), WP_SESSION_FEATURES_STANDARD, NULL,
@ -214,10 +214,10 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
}
g_assert_cmpuint (wp_session_get_default_endpoint (
WP_SESSION (fixture->proxy_session),
"Wp:defaultSink"), ==, 5);
WP_DIRECTION_INPUT), ==, 5);
g_assert_cmpuint (wp_session_get_default_endpoint (
WP_SESSION (fixture->proxy_session),
"Wp:defaultSource"), ==, 9);
WP_DIRECTION_OUTPUT), ==, 9);
/* setup change signals */
g_signal_connect (fixture->proxy_session, "prop-changed",
@ -231,7 +231,7 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
/* change default endpoint on the proxy */
wp_session_set_default_endpoint (WP_SESSION (fixture->proxy_session),
"Wp:defaultSink", 73);
WP_DIRECTION_INPUT, 73);
/* run until the change is on both sides */
fixture->n_events = 0;
@ -242,20 +242,20 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
g_assert_cmpuint (wp_session_get_default_endpoint (
WP_SESSION (fixture->proxy_session),
"Wp:defaultSink"), ==, 73);
WP_DIRECTION_INPUT), ==, 73);
g_assert_cmpuint (wp_session_get_default_endpoint (
WP_SESSION (fixture->proxy_session),
"Wp:defaultSource"), ==, 9);
WP_DIRECTION_OUTPUT), ==, 9);
g_assert_cmpuint (wp_session_get_default_endpoint (
WP_SESSION (session), "Wp:defaultSink"), ==, 73);
WP_SESSION (session), WP_DIRECTION_INPUT), ==, 73);
g_assert_cmpuint (wp_session_get_default_endpoint (
WP_SESSION (session), "Wp:defaultSource"), ==, 9);
WP_SESSION (session), WP_DIRECTION_OUTPUT), ==, 9);
/* change default endpoint on the exported */
fixture->n_events = 0;
wp_session_set_default_endpoint (WP_SESSION (session),
"Wp:defaultSource", 44);
WP_DIRECTION_OUTPUT, 44);
/* run until the change is on both sides */
g_main_loop_run (fixture->base.loop);
@ -264,10 +264,10 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
/* test round 3: verify the value change on both sides */
g_assert_cmpuint (wp_session_get_default_endpoint (
WP_SESSION (session), "Wp:defaultSource"), ==, 44);
WP_SESSION (session), WP_DIRECTION_OUTPUT), ==, 44);
g_assert_cmpuint (wp_session_get_default_endpoint (
WP_SESSION (fixture->proxy_session),
"Wp:defaultSource"), ==, 44);
WP_DIRECTION_OUTPUT), ==, 44);
/* change a property on the exported */
fixture->n_events = 0;

View file

@ -38,11 +38,11 @@ async_quit (WpCore *core, GAsyncResult *res, struct WpCliData * d)
}
static void
print_dev_endpoint (WpEndpoint *ep, WpSession *session, const gchar *type_name)
print_dev_endpoint (WpEndpoint *ep, WpSession *session, WpDirection dir)
{
guint32 id = wp_proxy_get_bound_id (WP_PROXY (ep));
gboolean is_default = (session && type_name != NULL &&
wp_session_get_default_endpoint (session, type_name) == id);
gboolean is_default = (session &&
wp_session_get_default_endpoint (session, dir) == id);
g_autoptr (WpSpaPod) ctrl = NULL;
gboolean has_audio_controls = FALSE;
gfloat volume = 0.0;
@ -95,7 +95,7 @@ list_endpoints (WpObjectManager * om, struct WpCliData * d)
NULL);
for (; wp_iterator_next (ep_it, &ep_val); g_value_unset (&ep_val)) {
WpEndpoint *ep = g_value_get_object (&ep_val);
print_dev_endpoint (ep, session, "Wp:defaultSource");
print_dev_endpoint (ep, session, WP_DIRECTION_OUTPUT);
}
g_clear_pointer (&ep_it, wp_iterator_unref);
@ -105,7 +105,7 @@ list_endpoints (WpObjectManager * om, struct WpCliData * d)
NULL);
for (; wp_iterator_next (ep_it, &ep_val); g_value_unset (&ep_val)) {
WpEndpoint *ep = g_value_get_object (&ep_val);
print_dev_endpoint (ep, session, "Wp:defaultSink");
print_dev_endpoint (ep, session, WP_DIRECTION_INPUT);
}
g_clear_pointer (&ep_it, wp_iterator_unref);
@ -135,7 +135,7 @@ set_default (WpObjectManager * om, struct WpCliData * d)
WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", id,
NULL);
if (ep) {
const gchar * type_name;
WpDirection dir;
g_autoptr (WpProperties) props = wp_proxy_get_properties (WP_PROXY (ep));
const gchar *sess_id_str = wp_properties_get (props, "session.id");
guint32 sess_id = sess_id_str ? atoi (sess_id_str) : 0;
@ -149,16 +149,16 @@ set_default (WpObjectManager * om, struct WpCliData * d)
}
if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Sink") == 0)
type_name = "Wp:defaultSink";
dir = WP_DIRECTION_INPUT;
else if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Source") == 0)
type_name = "Wp:defaultSource";
dir = WP_DIRECTION_OUTPUT;
else {
g_print ("%u: not a device endpoint\n", id);
g_main_loop_quit (d->loop);
return;
}
wp_session_set_default_endpoint (session, type_name, id);
wp_session_set_default_endpoint (session, dir, id);
wp_core_sync (d->core, NULL, (GAsyncReadyCallback) async_quit, d);
return;
}