bluez5: backend-ofono: don't do codec probe connections + add wait

Codec probe connections can trigger bad behavior from oFono if done when
device is busy (e.g. at connect), and they might be done at the same
time as A2DP transport is acquired which cannot work.

Also, oFono will not reply to DBus Acquire, if device does not complete
codec negotiation correctly. This is most likely to happen just after
device connect, when it is busy with other stuff (eg A2DP).

Remove codec probe connections altogether: instead, we guess mSBC if
mSBC is enabled and otherwise CVSD. If the guess turns out to be wrong,
which is unlikely (almost all devices have mSBC), we recreate the
transport with correct codec (from main loop, must not be done in
*_acquire because that can destroy nodes + unload the spa libs while
we're being called from there).

To avoid oFono DBus hangs at startup, add delay before marking the
profile connected, enforcing a time difference to A2DP operations.
This commit is contained in:
Pauli Virtanen 2022-03-03 23:32:33 +02:00 committed by Wim Taymans
parent 8026b65caa
commit 24fd273820
3 changed files with 139 additions and 37 deletions

View file

@ -837,7 +837,7 @@ struct spa_bt_device *spa_bt_device_find_by_address(struct spa_bt_monitor *monit
return NULL;
}
static void device_update_last_bluez_action_time(struct spa_bt_device *device)
void spa_bt_device_update_last_bluez_action_time(struct spa_bt_device *device)
{
struct timespec ts;
spa_system_clock_gettime(device->monitor->main_system, CLOCK_MONOTONIC, &ts);
@ -867,7 +867,7 @@ static struct spa_bt_device *device_create(struct spa_bt_monitor *monitor, const
spa_list_prepend(&monitor->device_list, &d->link);
device_update_last_bluez_action_time(d);
spa_bt_device_update_last_bluez_action_time(d);
return d;
}
@ -2595,7 +2595,7 @@ static bool a2dp_codec_switch_process_current(struct spa_bt_a2dp_codec_switch *s
goto next;
}
device_update_last_bluez_action_time(sw->device);
spa_bt_device_update_last_bluez_action_time(sw->device);
spa_log_info(sw->device->monitor->log, "a2dp codec switch %p: trying codec %s for endpoint %s, local endpoint %s",
sw, codec->name, ep->path, local_endpoint);
@ -2727,7 +2727,7 @@ static void a2dp_codec_switch_reply(DBusPendingCall *pending, void *user_data)
dbus_pending_call_unref(pending);
sw->pending = NULL;
device_update_last_bluez_action_time(device);
spa_bt_device_update_last_bluez_action_time(device);
if (!a2dp_codec_switch_goto_active(sw)) {
if (r != NULL)
@ -3030,7 +3030,7 @@ static DBusHandlerResult endpoint_set_configuration(DBusConnection *conn,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
device_update_last_bluez_action_time(transport->device);
spa_bt_device_update_last_bluez_action_time(transport->device);
if (profile & SPA_BT_PROFILE_A2DP_SOURCE) {
/* PW is the rendering device so it's responsible for reporting hardware volume. */