bluetooth: fix headset=auto ofono handover

Native backend implements HFP AG but not HFP HF yet, therefore headset=auto
functionality is still needed if HFP HF is required.

To make headset=auto work again, drop both HFP AG and HSP AG roles while
performing handover from native backend when oFono is detected running.

While at it, restore profile description to Headset Head Unit (HSP/HFP)
to note that HFP may be still provided via oFono backend.

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
This commit is contained in:
Igor V. Kovalenko 2021-01-28 09:08:53 +03:00 committed by Igor Kovalenko
parent 8491477b3e
commit 70171158ee
3 changed files with 25 additions and 16 deletions

View file

@ -41,6 +41,7 @@ struct pa_bluetooth_backend {
pa_dbus_connection *connection; pa_dbus_connection *connection;
pa_bluetooth_discovery *discovery; pa_bluetooth_discovery *discovery;
bool enable_hs_role; bool enable_hs_role;
bool enable_hfp_hf;
PA_LLIST_HEAD(pa_dbus_pending, pending); PA_LLIST_HEAD(pa_dbus_pending, pending);
}; };
@ -782,15 +783,24 @@ static void profile_done(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile
} }
} }
static void native_backend_apply_profile_registration_change(pa_bluetooth_backend *native_backend, bool enable_hs_role) {
if (enable_hs_role) {
profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
if (native_backend->enable_hfp_hf)
profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
} else {
profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
if (native_backend->enable_hfp_hf)
profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
}
}
void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *native_backend, bool enable_hs_role) { void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *native_backend, bool enable_hs_role) {
if (enable_hs_role == native_backend->enable_hs_role) if (enable_hs_role == native_backend->enable_hs_role)
return; return;
if (enable_hs_role) native_backend_apply_profile_registration_change(native_backend, enable_hs_role);
profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
else
profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
native_backend->enable_hs_role = enable_hs_role; native_backend->enable_hs_role = enable_hs_role;
} }
@ -814,12 +824,12 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
backend->discovery = y; backend->discovery = y;
backend->enable_hs_role = enable_hs_role; backend->enable_hs_role = enable_hs_role;
backend->enable_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(y);
if (backend->enable_hs_role)
native_backend_apply_profile_registration_change(backend, true);
if (enable_hs_role)
profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS); profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
if (pa_bluetooth_discovery_get_enable_native_hfp_hf(y))
profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
return backend; return backend;
} }
@ -830,10 +840,9 @@ void pa_bluetooth_native_backend_free(pa_bluetooth_backend *backend) {
pa_dbus_free_pending_list(&backend->pending); pa_dbus_free_pending_list(&backend->pending);
if (backend->enable_hs_role) if (backend->enable_hs_role)
profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_AG); native_backend_apply_profile_registration_change(backend, false);
profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS); profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
if (pa_bluetooth_discovery_get_enable_native_hfp_hf(backend->discovery))
profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
pa_dbus_connection_unref(backend->connection); pa_dbus_connection_unref(backend->connection);

View file

@ -1466,14 +1466,16 @@ void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is
if (y->headset_backend != HEADSET_BACKEND_AUTO) if (y->headset_backend != HEADSET_BACKEND_AUTO)
return; return;
/* If ofono starts running, all devices that might be connected to the HS role pa_bluetooth_native_backend_enable_hs_role(y->native_backend, !is_running);
/* If ofono starts running, all devices that might be connected to the HS roles or HFP AG role
* need to be disconnected, so that the devices can be handled by ofono */ * need to be disconnected, so that the devices can be handled by ofono */
if (is_running) { if (is_running) {
void *state; void *state;
pa_bluetooth_device *d; pa_bluetooth_device *d;
PA_HASHMAP_FOREACH(d, y->devices, state) { PA_HASHMAP_FOREACH(d, y->devices, state) {
if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG)) { if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG) || device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_HF)) {
DBusMessage *m; DBusMessage *m;
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, d->path, BLUEZ_DEVICE_INTERFACE, "Disconnect")); pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, d->path, BLUEZ_DEVICE_INTERFACE, "Disconnect"));
@ -1483,8 +1485,6 @@ void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is
} }
} }
} }
pa_bluetooth_native_backend_enable_hs_role(y->native_backend, !is_running);
} }
static void get_managed_objects_reply(DBusPendingCall *pending, void *userdata) { static void get_managed_objects_reply(DBusPendingCall *pending, void *userdata) {

View file

@ -1945,7 +1945,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, pa_bluetooth_pro
break; break;
case PA_BLUETOOTH_PROFILE_HSP_HS: case PA_BLUETOOTH_PROFILE_HSP_HS:
cp = pa_card_profile_new(name, _("Headset Head Unit (HSP)"), sizeof(pa_bluetooth_profile_t)); cp = pa_card_profile_new(name, _("Headset Head Unit (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 30; cp->priority = 30;
cp->n_sinks = 1; cp->n_sinks = 1;
cp->n_sources = 1; cp->n_sources = 1;