From 2fa1dfb2c610970fb63627b898e46aaccac239a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?= Date: Fri, 30 Dec 2016 09:58:43 +0200 Subject: [PATCH] [dbusif] Add option to route sources first. MER#1725 Some devices (at least OnePlus X) need to have sources routed before sinks to have properly functioning FM Radio. Add option to change the routing order for these devices. route_sources_first= default to false. --- src/dbusif.c | 17 ++++++++++++++++- src/dbusif.h | 2 +- src/module-policy-enforcement.c | 11 +++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/dbusif.c b/src/dbusif.c index af78306..766d273 100644 --- a/src/dbusif.c +++ b/src/dbusif.c @@ -67,6 +67,7 @@ struct pa_policy_dbusif { char *strrule; /* match rule to catch stream info signals */ int regist; /* wheter or not registered to policy daemon*/ int re_regist; + bool route_sources_first; }; struct actdsc { /* action descriptor */ @@ -129,7 +130,8 @@ struct pa_policy_dbusif *pa_policy_dbusif_init(struct userdata *u, const char *ifnam, const char *mypath, const char *pdpath, - const char *pdnam) + const char *pdnam, + bool route_sources_first) { pa_module *m = u->module; struct pa_policy_dbusif *dbusif = NULL; @@ -141,6 +143,8 @@ struct pa_policy_dbusif *pa_policy_dbusif_init(struct userdata *u, dbusif = pa_xnew0(struct pa_policy_dbusif, 1); + dbusif->route_sources_first = route_sources_first; + dbus_error_init(&error); dbusif->conn = pa_dbus_bus_get(m->core, DBUS_BUS_SYSTEM, &error); @@ -734,6 +738,17 @@ static int audio_route_parser(struct userdata *u, DBusMessageIter *actit) num_moving = pa_policy_group_start_move_all(u); pa_log_debug("Policy groups moving: %d", num_moving); + if (u->dbusif->route_sources_first) { + /* Following works only if MAX_ROUTING_DECISIONS is 2, so make sure this is + * caught if the value ever changes. */ + pa_assert_se(MAX_ROUTING_DECISIONS == 2); + if (num_decisions > 1 && decisions[0].class != pa_policy_route_to_source) { + struct routing_decision tmp = decisions[0]; + decisions[0] = decisions[1]; + decisions[1] = tmp; + } + } + /* Set profiles and ports while the groups are detached. */ for (i = 0; i < num_decisions; i++) { p = pa_proplist_new(); diff --git a/src/dbusif.h b/src/dbusif.h index ac8e221..6708cb9 100644 --- a/src/dbusif.h +++ b/src/dbusif.h @@ -7,7 +7,7 @@ struct pa_policy_dbusif; struct pa_policy_dbusif *pa_policy_dbusif_init(struct userdata *, const char *, const char *, const char *, - const char *); + const char *, bool); void pa_policy_dbusif_done(struct userdata *); void pa_policy_dbusif_send_device_state(struct userdata *, const char *, const char **, int); void pa_policy_dbusif_send_media_status(struct userdata *, const char *, diff --git a/src/module-policy-enforcement.c b/src/module-policy-enforcement.c index d9f6e98..5753134 100644 --- a/src/module-policy-enforcement.c +++ b/src/module-policy-enforcement.c @@ -60,6 +60,7 @@ PA_MODULE_USAGE( "dbus_policyd_name= " "null_sink_name= " "othermedia_preemption= " + "route_sources_first= Default false " "configdir=" ); @@ -71,6 +72,7 @@ static const char* const valid_modargs[] = { "dbus_policyd_name", "null_sink_name", "othermedia_preemption", + "route_sources_first", "configdir", NULL }; @@ -86,6 +88,7 @@ int pa__init(pa_module *m) { const char *pdnam; const char *nsnam; const char *preempt; + bool route_sources_first = false; const char *cfgdir; pa_assert(m); @@ -104,7 +107,11 @@ int pa__init(pa_module *m) { preempt = pa_modargs_get_value(ma, "othermedia_preemption", NULL); cfgdir = pa_modargs_get_value(ma, "configdir", NULL); - + if (pa_modargs_get_value_boolean(ma, "route_sources_first", &route_sources_first) < 0) { + pa_log("Failed to parse \"route_sources_first\" parameter."); + goto fail; + } + u = pa_xnew0(struct userdata, 1); m->userdata = u; u->core = m->core; @@ -122,7 +129,7 @@ int pa__init(pa_module *m) { u->groups = pa_policy_groupset_new(u); u->classify = pa_classify_new(u); u->context = pa_policy_context_new(u); - u->dbusif = pa_policy_dbusif_init(u, ifnam, mypath, pdpath, pdnam); + u->dbusif = pa_policy_dbusif_init(u, ifnam, mypath, pdpath, pdnam, route_sources_first); u->shared = pa_shared_data_get(u->core); if (u->scl == NULL || u->ssnk == NULL || u->ssrc == NULL ||