[pulseaudio-discuss] [RFC v0 1/5] card: Add card profile availability

Mikel Astiz mikel.astiz.oss at gmail.com
Wed Feb 13 05:48:12 PST 2013


From: Mikel Astiz <mikel.astiz at bmw-carit.de>

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



More information about the pulseaudio-discuss mailing list