From dd81386f9777a4e465741f03f40503245704104b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= Date: Tue, 21 May 2019 20:18:03 -0700 Subject: [PATCH 1/3] bluetooth: Set "computer" form-factor based on CoD The Class of Device field has a value for "computer" in its major portion. If the remote device behind a card is a computer, the form-factor should be set accordingly. --- src/modules/bluetooth/module-bluez5-device.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c index 0e49843c3..e6182050d 100644 --- a/src/modules/bluetooth/module-bluez5-device.c +++ b/src/modules/bluetooth/module-bluez5-device.c @@ -168,6 +168,7 @@ typedef enum pa_bluetooth_form_factor { PA_BLUETOOTH_FORM_FACTOR_CAR, PA_BLUETOOTH_FORM_FACTOR_HIFI, PA_BLUETOOTH_FORM_FACTOR_PHONE, + PA_BLUETOOTH_FORM_FACTOR_COMPUTER, } pa_bluetooth_form_factor_t; /* Run from main thread */ @@ -194,6 +195,8 @@ static pa_bluetooth_form_factor_t form_factor_from_class(uint32_t class_of_devic minor = (class_of_device >> 2) & 0x3F; switch (major) { + case 1: + return PA_BLUETOOTH_FORM_FACTOR_COMPUTER; case 2: return PA_BLUETOOTH_FORM_FACTOR_PHONE; case 4: @@ -234,6 +237,8 @@ static const char *form_factor_to_string(pa_bluetooth_form_factor_t ff) { return "hifi"; case PA_BLUETOOTH_FORM_FACTOR_PHONE: return "phone"; + case PA_BLUETOOTH_FORM_FACTOR_COMPUTER: + return "computer"; } pa_assert_not_reached(); @@ -1950,6 +1955,11 @@ static void create_card_ports(struct userdata *u, pa_hashmap *ports) { input_type = output_type = PA_DEVICE_PORT_TYPE_PHONE; break; + case PA_BLUETOOTH_FORM_FACTOR_COMPUTER: + name_prefix = "computer"; + input_description = output_description = _("Computer"); + break; + case PA_BLUETOOTH_FORM_FACTOR_UNKNOWN: break; } From da243cf1c7d4fe66415acba6ea386be8e71cf55c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= Date: Wed, 22 May 2019 17:10:16 -0700 Subject: [PATCH 2/3] core: Reduce priority of "computer" form factor If a sink or a source have the device.form_factor property set to "computer" it is a computer connected over Bluetooth, which should have a lower priority than other sinks/sources. --- src/pulsecore/sink.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 905e1db7b..6571c87c6 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -3608,6 +3608,12 @@ unsigned pa_device_init_priority(pa_proplist *p) { priority += 500; else if (pa_streq(s, "portable")) priority += 450; + else if (pa_streq(s, "computer")) + /* computers get a lower-than-base priority */ + priority += 0; + else + /* default base priority */ + priority += 100; } if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_BUS))) { From b81994296874dd853ceca931e448df09b7211ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= Date: Tue, 21 May 2019 20:28:49 -0700 Subject: [PATCH 3/3] switch-on-connect: Don't switch to Bluetooth computers Do not automatically switch if the bluetooth card represets a remote device with a computer form-factor. If the user is connecting two computers over Bluetooth they most likely want to use a non-audio feature like file transfer or network sharing. Automatic audio switching in these cases creates a very poor user experience. If the user actually wants to stream audio they can manually select the Bluetooth audio sink or source. --- src/modules/module-switch-on-connect.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c index 950ecbee2..a7c00194f 100644 --- a/src/modules/module-switch-on-connect.c +++ b/src/modules/module-switch-on-connect.c @@ -92,6 +92,16 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* return PA_HOOK_OK; } + /* Don't switch to computers implementing Bluetooth audio profiles */ + s = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_BUS); + if (pa_safe_streq(s, "bluetooth")) { + s = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_FORM_FACTOR); + if (pa_safe_streq(s, "computer")) { + pa_log_debug("Refusing to switch to Bluetooth sink on a computer"); + return PA_HOOK_OK; + } + } + /* Ignore virtual sinks if not configured otherwise on the command line */ if (u->ignore_virtual && !(sink->flags & PA_SINK_HARDWARE)) { pa_log_debug("Refusing to switch to virtual sink"); @@ -152,6 +162,16 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, return PA_HOOK_OK; } + /* Don't switch to computers implementing Bluetooth audio profiles */ + s = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_BUS); + if (pa_safe_streq(s, "bluetooth")) { + s = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_FORM_FACTOR); + if (pa_safe_streq(s, "computer")) { + pa_log_debug("Refusing to switch to Bluetooth source on a computer"); + return PA_HOOK_OK; + } + } + /* Ignore virtual sources if not configured otherwise on the command line */ if (u->ignore_virtual && !(source->flags & PA_SOURCE_HARDWARE)) { pa_log_debug("Refusing to switch to virtual source");