mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-11 13:30:02 -05:00
core: add a suspend cause flags field
This commit is contained in:
parent
3af5f8cb55
commit
00797b8b6e
16 changed files with 83 additions and 40 deletions
|
|
@ -244,19 +244,20 @@ int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pa_card_suspend(pa_card *c, pa_bool_t suspend) {
|
||||
int pa_card_suspend(pa_card *c, pa_bool_t suspend, pa_suspend_cause_t cause) {
|
||||
pa_sink *sink;
|
||||
pa_source *source;
|
||||
uint32_t idx;
|
||||
int ret = 0;
|
||||
|
||||
pa_assert(c);
|
||||
pa_assert(cause != 0);
|
||||
|
||||
for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx))
|
||||
ret -= pa_sink_suspend(sink, suspend) < 0;
|
||||
ret -= pa_sink_suspend(sink, suspend, cause) < 0;
|
||||
|
||||
for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx))
|
||||
ret -= pa_source_suspend(source, suspend) < 0;
|
||||
ret -= pa_source_suspend(source, suspend, cause) < 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,6 @@ void pa_card_free(pa_card *c);
|
|||
|
||||
int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save);
|
||||
|
||||
int pa_card_suspend(pa_card *c, pa_bool_t suspend);
|
||||
int pa_card_suspend(pa_card *c, pa_bool_t suspend, pa_suspend_cause_t cause);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1278,7 +1278,7 @@ static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *b
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((r = pa_sink_suspend(sink, suspend)) < 0)
|
||||
if ((r = pa_sink_suspend(sink, suspend, PA_SUSPEND_USER)) < 0)
|
||||
pa_strbuf_printf(buf, "Failed to resume/suspend sink: %s\n", pa_strerror(r));
|
||||
|
||||
return 0;
|
||||
|
|
@ -1314,7 +1314,7 @@ static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((r = pa_source_suspend(source, suspend)) < 0)
|
||||
if ((r = pa_source_suspend(source, suspend, PA_SUSPEND_USER)) < 0)
|
||||
pa_strbuf_printf(buf, "Failed to resume/suspend source: %s\n", pa_strerror(r));
|
||||
|
||||
return 0;
|
||||
|
|
@ -1339,10 +1339,10 @@ static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, p
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((r = pa_sink_suspend_all(c, suspend)) < 0)
|
||||
if ((r = pa_sink_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0)
|
||||
pa_strbuf_printf(buf, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r));
|
||||
|
||||
if ((r = pa_source_suspend_all(c, suspend)) < 0)
|
||||
if ((r = pa_source_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0)
|
||||
pa_strbuf_printf(buf, "Failed to resume/suspend all sources: %s\n", pa_strerror(r));
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ char *pa_sink_list_to_string(pa_core *c) {
|
|||
"\tdriver: <%s>\n"
|
||||
"\tflags: %s%s%s%s%s%s%s%s\n"
|
||||
"\tstate: %s\n"
|
||||
"\tsuspend cause: %s%s%s%s\n"
|
||||
"\tvolume: %s%s%s\n"
|
||||
"\t balance %0.2f\n"
|
||||
"\tbase volume: %s%s%s\n"
|
||||
|
|
@ -258,6 +259,10 @@ char *pa_sink_list_to_string(pa_core *c) {
|
|||
sink->flags & PA_SINK_FLAT_VOLUME ? "FLAT_VOLUME " : "",
|
||||
sink->flags & PA_SINK_DYNAMIC_LATENCY ? "DYNAMIC_LATENCY" : "",
|
||||
sink_state_to_string(pa_sink_get_state(sink)),
|
||||
sink->suspend_cause & PA_SUSPEND_USER ? "USER " : "",
|
||||
sink->suspend_cause & PA_SUSPEND_APPLICATION ? "APPLICATION " : "",
|
||||
sink->suspend_cause & PA_SUSPEND_IDLE ? "IDLE " : "",
|
||||
sink->suspend_cause & PA_SUSPEND_SESSION ? "SESSION" : "",
|
||||
pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, FALSE, FALSE)),
|
||||
sink->flags & PA_SINK_DECIBEL_VOLUME ? "\n\t " : "",
|
||||
sink->flags & PA_SINK_DECIBEL_VOLUME ? pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), pa_sink_get_volume(sink, FALSE, FALSE)) : "",
|
||||
|
|
@ -335,6 +340,7 @@ char *pa_source_list_to_string(pa_core *c) {
|
|||
"\tdriver: <%s>\n"
|
||||
"\tflags: %s%s%s%s%s%s%s\n"
|
||||
"\tstate: %s\n"
|
||||
"\tsuspend cause: %s%s%s%s\n"
|
||||
"\tvolume: %s%s%s\n"
|
||||
"\t balance %0.2f\n"
|
||||
"\tbase volume: %s%s%s\n"
|
||||
|
|
@ -358,6 +364,10 @@ char *pa_source_list_to_string(pa_core *c) {
|
|||
source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
|
||||
source->flags & PA_SOURCE_DYNAMIC_LATENCY ? "DYNAMIC_LATENCY" : "",
|
||||
source_state_to_string(pa_source_get_state(source)),
|
||||
source->suspend_cause & PA_SUSPEND_USER ? "USER " : "",
|
||||
source->suspend_cause & PA_SUSPEND_APPLICATION ? "APPLICATION " : "",
|
||||
source->suspend_cause & PA_SUSPEND_IDLE ? "IDLE " : "",
|
||||
source->suspend_cause & PA_SUSPEND_SESSION ? "SESSION" : "",
|
||||
pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source, FALSE)),
|
||||
source->flags & PA_SOURCE_DECIBEL_VOLUME ? "\n\t " : "",
|
||||
source->flags & PA_SOURCE_DECIBEL_VOLUME ? pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), pa_source_get_volume(source, FALSE)) : "",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,16 @@
|
|||
|
||||
typedef struct pa_core pa_core;
|
||||
|
||||
/* This is a bitmask that encodes the cause why a sink/source is
|
||||
* suspended. */
|
||||
typedef enum pa_suspend_cause {
|
||||
PA_SUSPEND_USER = 1, /* Exposed to the user via some protocol */
|
||||
PA_SUSPEND_APPLICATION = 2, /* Used by the device reservation logic */
|
||||
PA_SUSPEND_IDLE = 4, /* Used by module-suspend-on-idle */
|
||||
PA_SUSPEND_SESSION = 8, /* Used by module-hal for mark inactive sessions */
|
||||
PA_SUSPEND_ALL = 0xFFFF /* Magic cause that can be used to resume forcibly */
|
||||
} pa_suspend_cause_t;
|
||||
|
||||
#include <pulsecore/idxset.h>
|
||||
#include <pulsecore/hashmap.h>
|
||||
#include <pulsecore/memblock.h>
|
||||
|
|
|
|||
|
|
@ -947,10 +947,10 @@ static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const
|
|||
connection_write(c, &ok, sizeof(int32_t));
|
||||
|
||||
if (request == ESD_PROTO_STANDBY)
|
||||
ok = pa_sink_suspend_all(c->protocol->core, TRUE) >= 0;
|
||||
ok = pa_sink_suspend_all(c->protocol->core, TRUE, PA_SUSPEND_USER) >= 0;
|
||||
else {
|
||||
pa_assert(request == ESD_PROTO_RESUME);
|
||||
ok = pa_sink_suspend_all(c->protocol->core, FALSE) >= 0;
|
||||
ok = pa_sink_suspend_all(c->protocol->core, FALSE, PA_SUSPEND_USER) >= 0;
|
||||
}
|
||||
|
||||
connection_write(c, &ok, sizeof(int32_t));
|
||||
|
|
|
|||
|
|
@ -4098,7 +4098,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
|
|||
|
||||
pa_log_debug("%s all sinks", b ? "Suspending" : "Resuming");
|
||||
|
||||
if (pa_sink_suspend_all(c->protocol->core, b) < 0) {
|
||||
if (pa_sink_suspend_all(c->protocol->core, b, PA_SUSPEND_USER) < 0) {
|
||||
pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
|
||||
return;
|
||||
}
|
||||
|
|
@ -4112,7 +4112,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
|
|||
|
||||
CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
|
||||
|
||||
if (pa_sink_suspend(sink, b) < 0) {
|
||||
if (pa_sink_suspend(sink, b, PA_SUSPEND_USER) < 0) {
|
||||
pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
|
||||
return;
|
||||
}
|
||||
|
|
@ -4125,7 +4125,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
|
|||
|
||||
pa_log_debug("%s all sources", b ? "Suspending" : "Resuming");
|
||||
|
||||
if (pa_source_suspend_all(c->protocol->core, b) < 0) {
|
||||
if (pa_source_suspend_all(c->protocol->core, b, PA_SUSPEND_USER) < 0) {
|
||||
pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
|
||||
return;
|
||||
}
|
||||
|
|
@ -4140,7 +4140,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
|
|||
|
||||
CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY);
|
||||
|
||||
if (pa_source_suspend(source, b) < 0) {
|
||||
if (pa_source_suspend(source, b, PA_SUSPEND_USER) < 0) {
|
||||
pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ pa_sink* pa_sink_new(
|
|||
s->core = core;
|
||||
s->state = PA_SINK_INIT;
|
||||
s->flags = flags;
|
||||
s->suspend_cause = 0;
|
||||
s->name = pa_xstrdup(name);
|
||||
s->proplist = pa_proplist_copy(data->proplist);
|
||||
s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
|
||||
|
|
@ -499,11 +500,19 @@ int pa_sink_update_status(pa_sink*s) {
|
|||
}
|
||||
|
||||
/* Called from main context */
|
||||
int pa_sink_suspend(pa_sink *s, pa_bool_t suspend) {
|
||||
int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause) {
|
||||
pa_sink_assert_ref(s);
|
||||
pa_assert(PA_SINK_IS_LINKED(s->state));
|
||||
pa_assert(cause != 0);
|
||||
|
||||
if (suspend)
|
||||
s->suspend_cause |= cause;
|
||||
else
|
||||
s->suspend_cause &= ~cause;
|
||||
|
||||
pa_log_debug("Suspend cause of sink %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
|
||||
|
||||
if (s->suspend_cause)
|
||||
return sink_set_state(s, PA_SINK_SUSPENDED);
|
||||
else
|
||||
return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
|
||||
|
|
@ -1823,17 +1832,18 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
|
|||
}
|
||||
|
||||
/* Called from main thread */
|
||||
int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend) {
|
||||
int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) {
|
||||
pa_sink *sink;
|
||||
uint32_t idx;
|
||||
int ret = 0;
|
||||
|
||||
pa_core_assert_ref(c);
|
||||
pa_assert(cause != 0);
|
||||
|
||||
for (sink = PA_SINK(pa_idxset_first(c->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(c->sinks, &idx))) {
|
||||
int r;
|
||||
|
||||
if ((r = pa_sink_suspend(sink, suspend)) < 0)
|
||||
if ((r = pa_sink_suspend(sink, suspend, cause)) < 0)
|
||||
ret = r;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ struct pa_sink {
|
|||
pa_core *core;
|
||||
pa_sink_state_t state;
|
||||
pa_sink_flags_t flags;
|
||||
pa_suspend_cause_t suspend_cause;
|
||||
|
||||
char *name;
|
||||
char *driver; /* may be NULL */
|
||||
|
|
@ -252,8 +253,8 @@ size_t pa_sink_get_max_rewind(pa_sink *s);
|
|||
size_t pa_sink_get_max_request(pa_sink *s);
|
||||
|
||||
int pa_sink_update_status(pa_sink*s);
|
||||
int pa_sink_suspend(pa_sink *s, pa_bool_t suspend);
|
||||
int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend);
|
||||
int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause);
|
||||
int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause);
|
||||
|
||||
void pa_sink_update_flat_volume(pa_sink *s, pa_cvolume *new_volume);
|
||||
void pa_sink_propagate_flat_volume(pa_sink *s);
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ pa_source* pa_source_new(
|
|||
s->core = core;
|
||||
s->state = PA_SOURCE_INIT;
|
||||
s->flags = flags;
|
||||
s->suspend_cause = 0;
|
||||
s->name = pa_xstrdup(name);
|
||||
s->proplist = pa_proplist_copy(data->proplist);
|
||||
s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
|
||||
|
|
@ -427,13 +428,21 @@ int pa_source_update_status(pa_source*s) {
|
|||
}
|
||||
|
||||
/* Called from main context */
|
||||
int pa_source_suspend(pa_source *s, pa_bool_t suspend) {
|
||||
int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause) {
|
||||
pa_source_assert_ref(s);
|
||||
pa_assert(PA_SOURCE_IS_LINKED(s->state));
|
||||
pa_assert(cause != 0);
|
||||
|
||||
if (s->monitor_of)
|
||||
return -PA_ERR_NOTSUPPORTED;
|
||||
|
||||
if (suspend)
|
||||
s->suspend_cause |= cause;
|
||||
else
|
||||
s->suspend_cause &= ~cause;
|
||||
|
||||
pa_log_debug("Suspend cause of source %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
|
||||
|
||||
if (suspend)
|
||||
return source_set_state(s, PA_SOURCE_SUSPENDED);
|
||||
else
|
||||
|
|
@ -1032,12 +1041,13 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
|
|||
}
|
||||
|
||||
/* Called from main thread */
|
||||
int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) {
|
||||
int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) {
|
||||
uint32_t idx;
|
||||
pa_source *source;
|
||||
int ret = 0;
|
||||
|
||||
pa_core_assert_ref(c);
|
||||
pa_assert(cause != 0);
|
||||
|
||||
for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) {
|
||||
int r;
|
||||
|
|
@ -1045,7 +1055,7 @@ int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) {
|
|||
if (source->monitor_of)
|
||||
continue;
|
||||
|
||||
if ((r = pa_source_suspend(source, suspend)) < 0)
|
||||
if ((r = pa_source_suspend(source, suspend, cause)) < 0)
|
||||
ret = r;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ struct pa_source {
|
|||
pa_core *core;
|
||||
pa_source_state_t state;
|
||||
pa_source_flags_t flags;
|
||||
pa_suspend_cause_t suspend_cause;
|
||||
|
||||
char *name;
|
||||
char *driver; /* may be NULL */
|
||||
|
|
@ -231,8 +232,8 @@ void pa_source_get_latency_range(pa_source *s, pa_usec_t *min_latency, pa_usec_t
|
|||
size_t pa_source_get_max_rewind(pa_source *s);
|
||||
|
||||
int pa_source_update_status(pa_source*s);
|
||||
int pa_source_suspend(pa_source *s, pa_bool_t suspend);
|
||||
int pa_source_suspend_all(pa_core *c, pa_bool_t suspend);
|
||||
int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause);
|
||||
int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause);
|
||||
|
||||
void pa_source_set_volume(pa_source *source, const pa_cvolume *volume);
|
||||
const pa_cvolume *pa_source_get_volume(pa_source *source, pa_bool_t force_refresh);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue