From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx> Some cards are capable to announce if a specific profile is available or not, effectively predicting whether a profile switch would fail or would likely succeed. This can for example be useful for a UI that would gray out any unavailable profile. In addition, this information can be useful for internal modules implementing automatic profile-switching policies, such as module-switch-on-port-available or module-bluetooth-policy. In particular, this information is essential when a port is associated to multiple card profiles and therefore the port availability flag does not provide enough information. The port "bluetooth-output" falls into this category, for example, since it doesn't distinguish HSP/HFP from A2DP. --- src/pulse/def.h | 14 ++++++++++++++ src/pulsecore/card.c | 20 ++++++++++++++++++++ src/pulsecore/card.h | 4 ++++ src/pulsecore/core.h | 1 + 4 files changed, 39 insertions(+) diff --git a/src/pulse/def.h b/src/pulse/def.h index b939319..ccac28b 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -1006,6 +1006,20 @@ typedef enum pa_port_available { /** \endcond */ +/** Card profile availability + * \since 3.1 */ +typedef enum pa_profile_available { + PA_PROFILE_AVAILABLE_UNKNOWN = 0, /**< This card profile does not support availability or the information is not known */ + PA_PROFILE_AVAILABLE_NO = 1, /**< This card profile is not available, and a profile switch would fail */ + PA_PROFILE_AVAILABLE_YES = 2, /**< This card profile is available, and a profile switch would likely succeed */ +} pa_profile_available_t; + +/** \cond fulldocs */ +#define PA_PROFILE_AVAILABLE_UNKNOWN PA_PROFILE_AVAILABLE_UNKNOWN +#define PA_PROFILE_AVAILABLE_NO PA_PROFILE_AVAILABLE_NO +#define PA_PROFILE_AVAILABLE_YES PA_PROFILE_AVAILABLE_YES + +/** \endcond */ PA_C_DECL_END #endif diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c index afabc95..6335c9a 100644 --- a/src/pulsecore/card.c +++ b/src/pulsecore/card.c @@ -64,6 +64,26 @@ void pa_card_profile_free(pa_card_profile *c) { pa_xfree(c); } +void pa_card_profile_set_available(pa_card_profile *c, pa_profile_available_t available) { + pa_core *core; + + pa_assert(c); + pa_assert(c->card); /* Modify member variable directly during creation instead of using this function */ + + if (c->available == available) + return; + + c->available = available; + pa_log_debug("Setting card %s profile %s to availability status %s", c->card->name, c->name, + available == PA_PROFILE_AVAILABLE_YES ? "yes" : available == PA_PROFILE_AVAILABLE_NO ? "no" : "unknown"); + + /* Post subscriptions to the card which owns us */ + pa_assert_se(core = c->card->core); + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, c->card->index); + + pa_hook_fire(&core->hooks[PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED], c); +} + pa_card_new_data* pa_card_new_data_init(pa_card_new_data *data) { pa_assert(data); diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h index d72a293..0cdb3a3 100644 --- a/src/pulsecore/card.h +++ b/src/pulsecore/card.h @@ -35,6 +35,7 @@ typedef struct pa_card_profile { char *description; unsigned priority; + pa_profile_available_t available; /* PA_PROFILE_AVAILABLE_UNKNOWN, PA_PROFILE_AVAILABLE_NO or PA_PROFILE_AVAILABLE_YES */ /* We probably want to have different properties later on here */ unsigned n_sinks; @@ -93,6 +94,9 @@ typedef struct pa_card_new_data { pa_card_profile *pa_card_profile_new(const char *name, const char *description, size_t extra); void pa_card_profile_free(pa_card_profile *c); +/* The profile's available status has changed */ +void pa_card_profile_set_available(pa_card_profile *c, pa_profile_available_t available); + pa_card_new_data *pa_card_new_data_init(pa_card_new_data *data); void pa_card_new_data_set_name(pa_card_new_data *data, const char *name); void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile); diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 2099bb0..381897a 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -114,6 +114,7 @@ typedef enum pa_core_hook { PA_CORE_HOOK_CARD_UNLINK, PA_CORE_HOOK_CARD_PROFILE_CHANGED, PA_CORE_HOOK_CARD_PROFILE_ADDED, + PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED, PA_CORE_HOOK_PORT_AVAILABLE_CHANGED, PA_CORE_HOOK_PORT_ADDED, PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED, -- 1.8.1