Commit d7f95170 authored by João Paulo Rechi Vita's avatar João Paulo Rechi Vita Committed by PulseAudio Marge Bot
Browse files

bluetooth: Consider adapter UUIDs when evaluating profile support

The remote device list of UUIDs reflects which profiles are supported by
the remote device alone. We currently rely solely on this list to decide
if a certain card profile is supported, and thus should be created and
get connected.

This used to be accurate when the Bluetooth modules were first written,
but now BlueZ is more dynamic and local profile support can be added or
removed during runtime. The adapter's list of UUIDs is an accurate
representation of the profiles supported by the local host at a certain
moment.

This commit combines the list of UUIDs supported by remote device and
the list of UUIDs supported by the local host to determined whether a
Bluetooth profile is actually supported or not, and whether it should be
expected to get connected during device connection.

Part-of: <pulseaudio/pulseaudio!638>
parent b81b9958
......@@ -254,7 +254,7 @@ static const char *transport_state_to_string(pa_bluetooth_transport_state_t stat
return "invalid";
}
static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
bool pa_bluetooth_device_supports_profile(const pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
bool show_hfp, show_hsp;
if (device->enable_hfp_hf) {
......@@ -267,19 +267,29 @@ static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_pr
switch (profile) {
case PA_BLUETOOTH_PROFILE_A2DP_SINK:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SINK);
return !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SINK) &&
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE));
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE);
return !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE) &&
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_A2DP_SINK));
case PA_BLUETOOTH_PROFILE_HSP_HS:
return show_hsp
&& ( !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT));
&& ( !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS) &&
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HSP_AG)) ||
!!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT) &&
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HSP_AG)) );
case PA_BLUETOOTH_PROFILE_HSP_AG:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG);
return !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG) &&
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HSP_HS)) ||
!!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG) &&
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT));
case PA_BLUETOOTH_PROFILE_HFP_HF:
return show_hfp && !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
return show_hfp
&& !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF) &&
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HFP_AG));
case PA_BLUETOOTH_PROFILE_HFP_AG:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
return !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG) &&
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HFP_HF));
case PA_BLUETOOTH_PROFILE_OFF:
pa_assert_not_reached();
}
......@@ -299,7 +309,7 @@ static unsigned device_count_disconnected_profiles(pa_bluetooth_device *device)
unsigned count = 0;
for (profile = 0; profile < PA_BLUETOOTH_PROFILE_COUNT; profile++) {
if (!device_supports_profile(device, profile))
if (!pa_bluetooth_device_supports_profile(device, profile))
continue;
if (!device_is_profile_connected(device, profile))
......@@ -332,7 +342,7 @@ static void wait_for_profiles_cb(pa_mainloop_api *api, pa_time_event* event, con
if (device_is_profile_connected(device, profile))
continue;
if (!device_supports_profile(device, profile))
if (!pa_bluetooth_device_supports_profile(device, profile))
continue;
if (first)
......@@ -2081,7 +2091,7 @@ void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is
pa_bluetooth_device *d;
PA_HASHMAP_FOREACH(d, y->devices, state) {
if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG) || device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_HF)) {
if (pa_bluetooth_device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG) || pa_bluetooth_device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_HF)) {
DBusMessage *m;
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, d->path, BLUEZ_DEVICE_INTERFACE, "Disconnect"));
......
......@@ -215,6 +215,7 @@ void pa_bluetooth_transport_unlink(pa_bluetooth_transport *t);
void pa_bluetooth_transport_free(pa_bluetooth_transport *t);
void pa_bluetooth_transport_load_a2dp_sink_volume(pa_bluetooth_transport *t);
bool pa_bluetooth_device_supports_profile(const pa_bluetooth_device *device, pa_bluetooth_profile_t profile);
bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d);
bool pa_bluetooth_device_switch_codec(pa_bluetooth_device *device, pa_bluetooth_profile_t profile, pa_hashmap *capabilities_hashmap, const pa_a2dp_endpoint_conf *endpoint_conf, void (*codec_switch_cb)(bool, pa_bluetooth_profile_t profile, void *), void *userdata);
void pa_bluetooth_device_report_battery_level(pa_bluetooth_device *d, uint8_t level, const char *reporting_source);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment