[v9,8/8] bluetooth: policy: Set initial A2DP profile which bluez already activated

Submitted by Pali Rohár on April 22, 2019, 1:40 p.m.

Details

Message ID 20190422134002.16349-9-pali.rohar@gmail.com
State Superseded
Headers show
Series "New API for Bluetooth A2DP codecs" ( rev: 67 66 65 64 63 62 61 60 59 ) in PulseAudio

Not browsing as part of any series.

Commit Message

Pali Rohár April 22, 2019, 1:40 p.m.
Bluez and remote device decide which A2DP codec would use. Use this
selected A2DP codec as initial profile in pulseaudio.

In most cases it is either last used codec or codec with higher priority by
defined by remote device.
---
 src/modules/bluetooth/module-bluetooth-policy.c | 37 ++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c
index 9652a91fe..a0be36f1d 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -306,15 +306,44 @@  static pa_hook_result_t source_output_unlink_hook_callback(pa_core *c, pa_source
 }
 
 static pa_hook_result_t card_init_profile_hook_callback(pa_core *c, pa_card *card, void *userdata) {
+    pa_card_profile *iter_profile;
+    pa_card_profile *profile;
+    void *state;
+
     pa_assert(c);
     pa_assert(card);
 
-    /* If there are not some source outputs do nothing */
-    if (source_output_count(c, userdata) == 0)
+    /* If there are some source outputs set initial profile to some with source */
+    if (source_output_count(c, userdata) > 0) {
+        pa_log_debug("There is some source output, trying to choose initial profile with source for card %s", card->name);
+        switch_profile(card, false, userdata);
         return PA_HOOK_OK;
+    }
+
+    /* Otherwise switch to already active A2DP profile chosen by bluez */
+    pa_log_debug("Looking for A2DP profile activated by bluez for card %s", card->name);
 
-    /* Set initial profile to some with source */
-    switch_profile(card, false, userdata);
+    profile = NULL;
+
+    PA_HASHMAP_FOREACH(iter_profile, card->profiles, state) {
+        /* Bluez active profiles has "yes" availability */
+        if (iter_profile->available != PA_AVAILABLE_YES)
+            continue;
+
+        /* Ignore non-A2DP profiles */
+        if (!pa_startswith(iter_profile->name, "a2dp_"))
+            continue;
+
+        pa_log_debug("%s is active", iter_profile->name);
+
+        if (!profile || iter_profile->priority > profile->priority)
+            profile = iter_profile;
+    }
+
+    if (profile) {
+        pa_log_info("Setting active A2DP profile '%s' for card %s", profile->name, card->name);
+        pa_card_set_profile(card, profile, true);
+    }
 
     return PA_HOOK_OK;
 }