Skip to content
This repository was archived by the owner on Jan 25, 2021. It is now read-only.

Commit b02f9b6

Browse files
conte91EHfive
authored andcommitted
module-bluetooth-policy: Remember last used profile.
When switching profile to HSP due to the auto_switch parameter being set, make module-bluetooth-policy remember the current profile in use by the card. In this way, when the reverting to the original profile, the card won't fallback to the default A2DP profile, but will go back to whatever profile was being used at the time of switching (e.g. LDAC).
1 parent 5b546e1 commit b02f9b6

File tree

1 file changed

+35
-22
lines changed

1 file changed

+35
-22
lines changed

src/modules/bluetooth/module-bluetooth-policy.c

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ struct userdata {
6363
pa_hook_slot *card_init_profile_slot;
6464
pa_hook_slot *card_unlink_slot;
6565
pa_hook_slot *profile_available_changed_slot;
66-
pa_hashmap *will_need_revert_card_map;
66+
/** Map between cards and their previous profile. */
67+
pa_hashmap *old_profile_card_map;
6768
};
6869

6970
/* When a source is created, loopback it to default sink */
@@ -146,19 +147,24 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void *
146147
return PA_HOOK_OK;
147148
}
148149

149-
static void card_set_profile(struct userdata *u, pa_card *card, bool revert_to_a2dp)
150+
static void card_set_profile(struct userdata *u, pa_card *card, bool revert_to_a2dp, const char* new_profile)
150151
{
151152
pa_card_profile *profile;
152153
void *state;
153154

155+
/* The revert_to_a2dp and profile parameter are mutually exclusive. */
156+
pa_assert(revert_to_a2dp != (!new_profile));
157+
char* current_profile = pa_xstrdup(card->active_profile->name);
158+
bool switched = false;
159+
154160
/* Find available profile and activate it */
155161
PA_HASHMAP_FOREACH(profile, card->profiles, state) {
156162
if (profile->available == PA_AVAILABLE_NO)
157163
continue;
158164

159165
/* Check for correct profile based on revert_to_a2dp */
160166
if (revert_to_a2dp) {
161-
if (!pa_streq(profile->name, "a2dp") && !pa_bt_prefix_eq(profile->name, "a2dp_sink"))
167+
if (!pa_streq(profile->name, new_profile))
162168
continue;
163169
} else {
164170
if (!pa_streq(profile->name, "hsp") && !pa_streq(profile->name, "headset_head_unit"))
@@ -171,48 +177,58 @@ static void card_set_profile(struct userdata *u, pa_card *card, bool revert_to_a
171177
pa_log_warn("Could not set profile '%s'", profile->name);
172178
continue;
173179
}
174-
175-
/* When we are not in revert_to_a2dp phase flag this card for will_need_revert */
176-
if (!revert_to_a2dp)
177-
pa_hashmap_put(u->will_need_revert_card_map, card, PA_INT_TO_PTR(1));
178-
180+
switched = true;
179181
break;
180182
}
183+
/*
184+
* When we are not in revert_to_a2dp phase flag that this card will need a revert.
185+
* Save the old profile.
186+
*/
187+
if (switched && !revert_to_a2dp) {
188+
pa_hashmap_put(u->old_profile_card_map, card, current_profile);
189+
} else {
190+
free(current_profile);
191+
}
181192
}
182193

183194
/* Switch profile for one card */
184195
static void switch_profile(pa_card *card, bool revert_to_a2dp, void *userdata) {
185196
struct userdata *u = userdata;
186197
const char *s;
198+
const char *old_profile = NULL;
187199

188200
/* Only consider bluetooth cards */
189201
s = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_BUS);
190202
if (!s || !pa_streq(s, "bluetooth"))
191203
return;
192204

193205
if (revert_to_a2dp) {
194-
/* In revert_to_a2dp phase only consider cards with will_need_revert flag and remove it */
195-
if (!pa_hashmap_remove(u->will_need_revert_card_map, card))
196-
return;
206+
/* In revert_to_a2dp phase only consider cards with an old profile stored and remove it. */
207+
if (!(old_profile = pa_hashmap_get(u->old_profile_card_map, card)))
208+
goto fail;
197209

198210
/* Skip card if does not have active hsp profile */
199211
if (!pa_streq(card->active_profile->name, "hsp") && !pa_streq(card->active_profile->name, "headset_head_unit"))
200-
return;
212+
goto fail;
201213

202214
/* Skip card if already has active a2dp profile */
203215
if (pa_streq(card->active_profile->name, "a2dp") || pa_strneq(card->active_profile->name, "a2dp_sink", strlen("a2dp_sink")))
204-
return;
216+
goto fail;
205217
} else {
206218
/* Skip card if does not have active a2dp profile */
207219
if (!pa_streq(card->active_profile->name, "a2dp") && !pa_bt_prefix_eq(card->active_profile->name, "a2dp_sink"))
208-
return;
220+
goto fail;
209221

210222
/* Skip card if already has active hsp profile */
211223
if (pa_streq(card->active_profile->name, "hsp") || pa_streq(card->active_profile->name, "headset_head_unit"))
212-
return;
224+
goto fail;
213225
}
214226

215-
card_set_profile(u, card, revert_to_a2dp);
227+
card_set_profile(u, card, revert_to_a2dp, old_profile);
228+
fail:
229+
if (revert_to_a2dp) {
230+
pa_hashmap_remove_and_free(u->old_profile_card_map, card);
231+
}
216232
}
217233

218234
/* Return true if we should ignore this source output */
@@ -316,10 +332,7 @@ static pa_hook_result_t card_init_profile_hook_callback(pa_core *c, pa_card *car
316332
return PA_HOOK_OK;
317333

318334
/* Set initial profile to hsp */
319-
card_set_profile(u, card, false);
320-
321-
/* Flag this card for will_need_revert */
322-
pa_hashmap_put(u->will_need_revert_card_map, card, PA_INT_TO_PTR(1));
335+
card_set_profile(u, card, false, NULL);
323336
return PA_HOOK_OK;
324337
}
325338

@@ -452,7 +465,7 @@ int pa__init(pa_module *m) {
452465
goto fail;
453466
}
454467

455-
u->will_need_revert_card_map = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
468+
u->old_profile_card_map = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
456469

457470
u->source_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL,
458471
(pa_hook_cb_t) source_put_hook_callback, u);
@@ -517,7 +530,7 @@ void pa__done(pa_module *m) {
517530
if (u->profile_available_changed_slot)
518531
pa_hook_slot_free(u->profile_available_changed_slot);
519532

520-
pa_hashmap_free(u->will_need_revert_card_map);
533+
pa_hashmap_free(u->old_profile_card_map);
521534

522535
pa_xfree(u);
523536
}

0 commit comments

Comments
 (0)