mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
bluez5: different icon for A2DP & HFP output routes
Set different icons for A2DP & HFP output routes, so that they look different (in Gnome). Don't call the non-HFP output route as "headset" or "handsfree" in this case, to be less ambiguous about microphone availability. Also set device.icon-name for the device too.
This commit is contained in:
parent
9586ef891e
commit
270eda63a9
3 changed files with 71 additions and 6 deletions
|
|
@ -1721,8 +1721,9 @@ static void emit_device_info(struct spa_bt_monitor *monitor,
|
||||||
{
|
{
|
||||||
struct spa_device_object_info info;
|
struct spa_device_object_info info;
|
||||||
char dev[32], name[128], class[16], vendor_id[64], product_id[64], product_id_tot[67];
|
char dev[32], name[128], class[16], vendor_id[64], product_id[64], product_id_tot[67];
|
||||||
struct spa_dict_item items[23];
|
struct spa_dict_item items[24];
|
||||||
uint32_t n_items = 0;
|
uint32_t n_items = 0;
|
||||||
|
enum spa_bt_form_factor ff;
|
||||||
|
|
||||||
info = SPA_DEVICE_OBJECT_INFO_INIT();
|
info = SPA_DEVICE_OBJECT_INFO_INIT();
|
||||||
info.type = SPA_TYPE_INTERFACE_Device;
|
info.type = SPA_TYPE_INTERFACE_Device;
|
||||||
|
|
@ -1731,6 +1732,8 @@ static void emit_device_info(struct spa_bt_monitor *monitor,
|
||||||
SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS;
|
SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS;
|
||||||
info.flags = 0;
|
info.flags = 0;
|
||||||
|
|
||||||
|
ff = spa_bt_form_factor_from_class(device->bluetooth_class);
|
||||||
|
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "bluez5");
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "bluez5");
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_BUS, "bluetooth");
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_BUS, "bluetooth");
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Audio/Device");
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Audio/Device");
|
||||||
|
|
@ -1745,9 +1748,8 @@ static void emit_device_info(struct spa_bt_monitor *monitor,
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_VENDOR_ID, vendor_id);
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_VENDOR_ID, vendor_id);
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_PRODUCT_ID, product_id_tot);
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_PRODUCT_ID, product_id_tot);
|
||||||
}
|
}
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_FORM_FACTOR,
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_FORM_FACTOR, spa_bt_form_factor_name(ff));
|
||||||
spa_bt_form_factor_name(
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ICON_NAME, spa_bt_form_factor_icon_name(ff));
|
||||||
spa_bt_form_factor_from_class(device->bluetooth_class)));
|
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_STRING, device->address);
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_STRING, device->address);
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_BLUEZ5_ICON, device->icon);
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_BLUEZ5_ICON, device->icon);
|
||||||
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_BLUEZ5_PATH, device->path);
|
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_API_BLUEZ5_PATH, device->path);
|
||||||
|
|
|
||||||
|
|
@ -534,7 +534,7 @@ static void emit_device_set_node(struct impl *this, uint32_t id)
|
||||||
struct spa_bt_device *device = this->bt_dev;
|
struct spa_bt_device *device = this->bt_dev;
|
||||||
struct node *node = &this->nodes[id];
|
struct node *node = &this->nodes[id];
|
||||||
struct spa_device_object_info info;
|
struct spa_device_object_info info;
|
||||||
struct spa_dict_item items[8];
|
struct spa_dict_item items[9];
|
||||||
char str_id[32], members_json[8192], channels_json[512];
|
char str_id[32], members_json[8192], channels_json[512];
|
||||||
struct device_set_member *members;
|
struct device_set_member *members;
|
||||||
uint32_t n_members;
|
uint32_t n_members;
|
||||||
|
|
@ -2150,6 +2150,22 @@ static bool profile_has_route(uint32_t profile, uint32_t route)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool device_has_route(struct impl *this, uint32_t route)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_DUPLEX)
|
||||||
|
found = found || profile_has_route(DEVICE_PROFILE_A2DP, route);
|
||||||
|
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_BAP_AUDIO)
|
||||||
|
found = found || profile_has_route(DEVICE_PROFILE_BAP, route);
|
||||||
|
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_HEADSET_HEAD_UNIT)
|
||||||
|
found = found || profile_has_route(DEVICE_PROFILE_HSP_HFP, route);
|
||||||
|
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_ASHA_SINK)
|
||||||
|
found = found || profile_has_route(DEVICE_PROFILE_ASHA, route);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
static struct spa_pod *build_route(struct impl *this, struct spa_pod_builder *b,
|
static struct spa_pod *build_route(struct impl *this, struct spa_pod_builder *b,
|
||||||
uint32_t id, uint32_t route, uint32_t profile)
|
uint32_t id, uint32_t route, uint32_t profile)
|
||||||
{
|
{
|
||||||
|
|
@ -2157,6 +2173,7 @@ static struct spa_pod *build_route(struct impl *this, struct spa_pod_builder *b,
|
||||||
struct spa_pod_frame f[2];
|
struct spa_pod_frame f[2];
|
||||||
enum spa_direction direction;
|
enum spa_direction direction;
|
||||||
const char *name_prefix, *description, *hfp_description, *port_type;
|
const char *name_prefix, *description, *hfp_description, *port_type;
|
||||||
|
const char *port_icon_name = NULL;
|
||||||
enum spa_bt_form_factor ff;
|
enum spa_bt_form_factor ff;
|
||||||
enum spa_bluetooth_audio_codec codec;
|
enum spa_bluetooth_audio_codec codec;
|
||||||
enum spa_param_availability available;
|
enum spa_param_availability available;
|
||||||
|
|
@ -2250,6 +2267,20 @@ static struct spa_pod *build_route(struct impl *this, struct spa_pod_builder *b,
|
||||||
dev = DEVICE_ID_SINK;
|
dev = DEVICE_ID_SINK;
|
||||||
available = this->device_set.sink_enabled ?
|
available = this->device_set.sink_enabled ?
|
||||||
SPA_PARAM_AVAILABILITY_no : SPA_PARAM_AVAILABILITY_yes;
|
SPA_PARAM_AVAILABILITY_no : SPA_PARAM_AVAILABILITY_yes;
|
||||||
|
|
||||||
|
if (device_has_route(this, ROUTE_HF_OUTPUT)) {
|
||||||
|
/* Distinguish A2DP vs. HFP output routes */
|
||||||
|
switch (ff) {
|
||||||
|
case SPA_BT_FORM_FACTOR_HEADSET:
|
||||||
|
case SPA_BT_FORM_FACTOR_HANDSFREE:
|
||||||
|
port_icon_name = spa_bt_form_factor_icon_name(SPA_BT_FORM_FACTOR_HEADPHONE);
|
||||||
|
/* Don't call it "headset", the HF one has the mic */
|
||||||
|
description = _("Headphone");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ROUTE_HF_OUTPUT:
|
case ROUTE_HF_OUTPUT:
|
||||||
direction = SPA_DIRECTION_OUTPUT;
|
direction = SPA_DIRECTION_OUTPUT;
|
||||||
|
|
@ -2257,6 +2288,8 @@ static struct spa_pod *build_route(struct impl *this, struct spa_pod_builder *b,
|
||||||
description = hfp_description;
|
description = hfp_description;
|
||||||
dev = DEVICE_ID_SINK;
|
dev = DEVICE_ID_SINK;
|
||||||
available = SPA_PARAM_AVAILABILITY_yes;
|
available = SPA_PARAM_AVAILABILITY_yes;
|
||||||
|
if (device_has_route(this, ROUTE_OUTPUT))
|
||||||
|
port_icon_name = spa_bt_form_factor_icon_name(SPA_BT_FORM_FACTOR_HEADSET);
|
||||||
break;
|
break;
|
||||||
case ROUTE_SET_INPUT:
|
case ROUTE_SET_INPUT:
|
||||||
if (!(this->device_set.source_enabled && this->device_set.leader))
|
if (!(this->device_set.source_enabled && this->device_set.leader))
|
||||||
|
|
@ -2292,11 +2325,16 @@ static struct spa_pod *build_route(struct impl *this, struct spa_pod_builder *b,
|
||||||
0);
|
0);
|
||||||
spa_pod_builder_prop(b, SPA_PARAM_ROUTE_info, 0);
|
spa_pod_builder_prop(b, SPA_PARAM_ROUTE_info, 0);
|
||||||
spa_pod_builder_push_struct(b, &f[1]);
|
spa_pod_builder_push_struct(b, &f[1]);
|
||||||
spa_pod_builder_int(b, 1);
|
spa_pod_builder_int(b, port_icon_name ? 2 : 1);
|
||||||
spa_pod_builder_add(b,
|
spa_pod_builder_add(b,
|
||||||
SPA_POD_String("port.type"),
|
SPA_POD_String("port.type"),
|
||||||
SPA_POD_String(port_type),
|
SPA_POD_String(port_type),
|
||||||
NULL);
|
NULL);
|
||||||
|
if (port_icon_name)
|
||||||
|
spa_pod_builder_add(b,
|
||||||
|
SPA_POD_String("device.icon-name"),
|
||||||
|
SPA_POD_String(port_icon_name),
|
||||||
|
NULL);
|
||||||
spa_pod_builder_pop(b, &f[1]);
|
spa_pod_builder_pop(b, &f[1]);
|
||||||
spa_pod_builder_prop(b, SPA_PARAM_ROUTE_profiles, 0);
|
spa_pod_builder_prop(b, SPA_PARAM_ROUTE_profiles, 0);
|
||||||
spa_pod_builder_push_array(b, &f[1]);
|
spa_pod_builder_push_array(b, &f[1]);
|
||||||
|
|
|
||||||
|
|
@ -427,6 +427,31 @@ static inline const char *spa_bt_form_factor_name(enum spa_bt_form_factor ff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *spa_bt_form_factor_icon_name(enum spa_bt_form_factor ff)
|
||||||
|
{
|
||||||
|
switch (ff) {
|
||||||
|
case SPA_BT_FORM_FACTOR_HEADSET:
|
||||||
|
return "audio-headset-bluetooth";
|
||||||
|
case SPA_BT_FORM_FACTOR_HANDSFREE:
|
||||||
|
return "audio-handsfree-bluetooth";
|
||||||
|
case SPA_BT_FORM_FACTOR_MICROPHONE:
|
||||||
|
return "audio-input-microphone-bluetooth";
|
||||||
|
case SPA_BT_FORM_FACTOR_SPEAKER:
|
||||||
|
return "audio-speakers-bluetooth";
|
||||||
|
case SPA_BT_FORM_FACTOR_HEADPHONE:
|
||||||
|
return "audio-headphones-bluetooth";
|
||||||
|
case SPA_BT_FORM_FACTOR_PORTABLE:
|
||||||
|
return "multimedia-player-bluetooth";
|
||||||
|
case SPA_BT_FORM_FACTOR_PHONE:
|
||||||
|
return "phone-bluetooth";
|
||||||
|
case SPA_BT_FORM_FACTOR_CAR:
|
||||||
|
case SPA_BT_FORM_FACTOR_HIFI:
|
||||||
|
case SPA_BT_FORM_FACTOR_UNKNOWN:
|
||||||
|
default:
|
||||||
|
return "audio-card-bluetooth";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline enum spa_bt_form_factor spa_bt_form_factor_from_class(uint32_t bluetooth_class)
|
static inline enum spa_bt_form_factor spa_bt_form_factor_from_class(uint32_t bluetooth_class)
|
||||||
{
|
{
|
||||||
uint32_t major, minor;
|
uint32_t major, minor;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue