modules: add various checks to avoid selecting objects that are not linked or in another unclear state

This commit is contained in:
Lennart Poettering 2009-08-16 00:45:23 +02:00
parent 2a39663ab6
commit 4c29ba9c33
4 changed files with 92 additions and 16 deletions

View file

@ -127,6 +127,9 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
if (s == def) if (s == def)
continue; continue;
if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)))
continue;
if (role_match(s->proplist, role)) { if (role_match(s->proplist, role)) {
new_data->sink = s; new_data->sink = s;
new_data->save_sink = FALSE; new_data->save_sink = FALSE;
@ -173,6 +176,9 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
if (s == def) if (s == def)
continue; continue;
if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
continue;
if (role_match(s->proplist, role)) { if (role_match(s->proplist, role)) {
new_data->source = s; new_data->source = s;
new_data->save_source = FALSE; new_data->save_source = FALSE;
@ -201,6 +207,17 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
if (si->save_sink) if (si->save_sink)
continue; continue;
/* Skip this if it is already in the process of being moved
* anyway */
if (!si->sink)
continue;
/* It might happen that a stream and a sink are set up at the
same time, in which case we want to make sure we don't
interfere with that */
if (!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(si)))
continue;
if (!(role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE))) if (!(role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE)))
continue; continue;
@ -237,6 +254,17 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (so->direct_on_input) if (so->direct_on_input)
continue; continue;
/* Skip this if it is already in the process of being moved
* anyway */
if (!so->source)
continue;
/* It might happen that a stream and a source are set up at the
same time, in which case we want to make sure we don't
interfere with that */
if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(so)))
continue;
if (!(role = pa_proplist_gets(so->proplist, PA_PROP_MEDIA_ROLE))) if (!(role = pa_proplist_gets(so->proplist, PA_PROP_MEDIA_ROLE)))
continue; continue;
@ -275,24 +303,28 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
uint32_t jdx; uint32_t jdx;
pa_sink *d; pa_sink *d;
if (!si->sink)
continue;
if (!(role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE))) if (!(role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE)))
continue; continue;
/* Would the default sink fit? If so, let's use it */ /* Would the default sink fit? If so, let's use it */
if (def != sink && role_match(def->proplist, role)) { if (def != sink && role_match(def->proplist, role))
pa_sink_input_move_to(si, def, FALSE); if (pa_sink_input_move_to(si, def, FALSE) >= 0)
continue; continue;
}
/* Try to find some other fitting sink */ /* Try to find some other fitting sink */
PA_IDXSET_FOREACH(d, c->sinks, jdx) { PA_IDXSET_FOREACH(d, c->sinks, jdx) {
if (d == def || d == sink) if (d == def || d == sink)
continue; continue;
if (role_match(d->proplist, role)) { if (!PA_SINK_IS_LINKED(pa_sink_get_state(d)))
pa_sink_input_move_to(si, d, FALSE); continue;
break;
} if (role_match(d->proplist, role))
if (pa_sink_input_move_to(si, d, FALSE) >= 0)
break;
} }
} }
@ -325,6 +357,9 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
if (so->direct_on_input) if (so->direct_on_input)
continue; continue;
if (!so->source)
continue;
if (!(role = pa_proplist_gets(so->proplist, PA_PROP_MEDIA_ROLE))) if (!(role = pa_proplist_gets(so->proplist, PA_PROP_MEDIA_ROLE)))
continue; continue;
@ -339,6 +374,9 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
if (d == def || d == source) if (d == def || d == source)
continue; continue;
if (!PA_SOURCE_IS_LINKED(pa_source_get_state(d)))
continue;
if (role_match(d->proplist, role) && !source->monitor_of == !d->monitor_of) { if (role_match(d->proplist, role) && !source->monitor_of == !d->monitor_of) {
pa_source_output_move_to(so, d, FALSE); pa_source_output_move_to(so, d, FALSE);
break; break;

View file

@ -71,6 +71,9 @@ static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip
if (target == skip) if (target == skip)
continue; continue;
if (!PA_SINK_IS_LINKED(pa_sink_get_state(target)))
continue;
if (pa_sink_input_may_move_to(i, target)) if (pa_sink_input_may_move_to(i, target))
return target; return target;
} }
@ -159,6 +162,9 @@ static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_sou
if (!target->monitor_of != !skip->monitor_of) if (!target->monitor_of != !skip->monitor_of)
continue; continue;
if (!PA_SOURCE_IS_LINKED(pa_source_get_state(target)))
continue;
if (pa_source_output_may_move_to(o, target)) if (pa_source_output_may_move_to(o, target))
return target; return target;
} }

View file

@ -540,6 +540,11 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
if (si->save_sink) if (si->save_sink)
continue; continue;
/* Skip this if it is already in the process of being moved
* anyway */
if (!si->sink)
continue;
/* It might happen that a stream and a sink are set up at the /* It might happen that a stream and a sink are set up at the
same time, in which case we want to make sure we don't same time, in which case we want to make sure we don't
interfere with that */ interfere with that */
@ -584,6 +589,10 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (so->direct_on_input) if (so->direct_on_input)
continue; continue;
/* Skip this if it is already in the process of being moved anyway */
if (!so->source)
continue;
/* It might happen that a stream and a sink are set up at the /* It might happen that a stream and a sink are set up at the
same time, in which case we want to make sure we don't same time, in which case we want to make sure we don't
interfere with that */ interfere with that */
@ -623,6 +632,9 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
char *name; char *name;
struct entry *e; struct entry *e;
if (!si->sink)
continue;
if (!(name = get_name(si->proplist, "sink-input"))) if (!(name = get_name(si->proplist, "sink-input")))
continue; continue;
@ -663,6 +675,12 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
char *name; char *name;
struct entry *e; struct entry *e;
if (so->direct_on_input)
continue;
if (!so->source)
continue;
if (!(name = get_name(so->proplist, "source-output"))) if (!(name = get_name(so->proplist, "source-output")))
continue; continue;

View file

@ -223,6 +223,9 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) {
pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) { pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) {
pa_assert(c); pa_assert(c);
if (s && !PA_SINK_IS_LINKED(pa_sink_get_state(s)))
return NULL;
if (c->default_sink != s) { if (c->default_sink != s) {
c->default_sink = s; c->default_sink = s;
pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
@ -234,6 +237,9 @@ pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) {
pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) { pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
pa_assert(c); pa_assert(c);
if (s && !PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
return NULL;
if (c->default_source != s) { if (c->default_source != s) {
c->default_source = s; c->default_source = s;
pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
@ -244,14 +250,19 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
pa_sink *pa_namereg_get_default_sink(pa_core *c) { pa_sink *pa_namereg_get_default_sink(pa_core *c) {
pa_sink *s; pa_sink *s;
uint32_t idx;
pa_assert(c); pa_assert(c);
if (c->default_sink) if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)))
return c->default_sink; return c->default_sink;
if ((s = pa_idxset_first(c->sinks, NULL))) /* FIXME: the selection here should be based priority values on
return pa_namereg_set_default_sink(c, s); * the sinks */
PA_IDXSET_FOREACH(s, c->sinks, idx)
if (PA_SINK_IS_LINKED(pa_sink_get_state(s)))
return pa_namereg_set_default_sink(c, s);
return NULL; return NULL;
} }
@ -262,15 +273,18 @@ pa_source *pa_namereg_get_default_source(pa_core *c) {
pa_assert(c); pa_assert(c);
if (c->default_source) if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source)))
return c->default_source; return c->default_source;
for (s = PA_SOURCE(pa_idxset_first(c->sources, &idx)); s; s = PA_SOURCE(pa_idxset_next(c->sources, &idx))) /* First, try to find one that isn't a monitor */
if (!s->monitor_of) PA_IDXSET_FOREACH(s, c->sources, idx)
if (!s->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
return pa_namereg_set_default_source(c, s); return pa_namereg_set_default_source(c, s);
if ((s = pa_idxset_first(c->sources, NULL))) /* Then, fallback to a monitor */
return pa_namereg_set_default_source(c, s); PA_IDXSET_FOREACH(s, c->sources, idx)
if (PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
return pa_namereg_set_default_source(c, s);
return NULL; return NULL;
} }