From a9b8aa27c1b0fc37e2fff8ca97266bd5390678fe Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 19 Apr 2021 13:21:32 +0200 Subject: [PATCH] media-session: improve bluetooth icon name Move the icon we get from bluez to a separate property, it is not a good icon to show. Copy form factor from device to node properties. Set device.bus in the device properties and copy it to the node properties. Use form factor and bus to make a nice icon-name for the node and device. Fixes #1064 --- spa/include/spa/utils/keys.h | 1 + spa/plugins/bluez5/bluez5-dbus.c | 6 +- src/examples/media-session/alsa-monitor.c | 8 +-- src/examples/media-session/bluez-monitor.c | 72 +++++++++++++++++++++- 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/spa/include/spa/utils/keys.h b/spa/include/spa/utils/keys.h index 6eeb59906..ae1830dfa 100644 --- a/spa/include/spa/utils/keys.h +++ b/spa/include/spa/utils/keys.h @@ -114,6 +114,7 @@ extern "C" { #define SPA_KEY_API_BLUEZ5_ADDRESS "api.bluez5.address" /**< a bluetooth address */ #define SPA_KEY_API_BLUEZ5_CODEC "api.bluez5.codec" /**< a bluetooth codec */ #define SPA_KEY_API_BLUEZ5_CLASS "api.bluez5.class" /**< a bluetooth class */ +#define SPA_KEY_API_BLUEZ5_ICON "api.bluez5.icon" /**< a bluetooth icon */ /** keys for jack api */ #define SPA_KEY_API_JACK "api.jack" /**< key for the JACK api */ diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index d3137f5ad..f1e7953f1 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -768,16 +768,17 @@ static int device_connected_old(struct spa_bt_monitor *monitor, struct spa_bt_de info.flags = 0; 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_MEDIA_CLASS, "Audio/Device"); snprintf(name, sizeof(name), "bluez_card.%s", device->address); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_NAME, name); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_DESCRIPTION, device->name); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ALIAS, device->alias); - items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ICON_NAME, device->icon); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_FORM_FACTOR, spa_bt_form_factor_name( 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_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_ADDRESS, device->address); snprintf(dev, sizeof(dev), "pointer:%p", device); @@ -850,16 +851,17 @@ static int device_connected(struct spa_bt_monitor *monitor, struct spa_bt_device info.flags = 0; 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_MEDIA_CLASS, "Audio/Device"); snprintf(name, sizeof(name), "bluez_card.%s", device->address); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_NAME, name); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_DESCRIPTION, device->name); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ALIAS, device->alias); - items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ICON_NAME, device->icon); items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_FORM_FACTOR, spa_bt_form_factor_name( 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_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_ADDRESS, device->address); snprintf(dev, sizeof(dev), "pointer:%p", device); diff --git a/src/examples/media-session/alsa-monitor.c b/src/examples/media-session/alsa-monitor.c index d41aebf78..a67c7fe64 100644 --- a/src/examples/media-session/alsa-monitor.c +++ b/src/examples/media-session/alsa-monitor.c @@ -203,7 +203,7 @@ static const struct sm_object_methods node_methods = { .release = node_release, }; -static void update_icon_name(struct pw_properties *p, struct pw_properties *props, bool is_sink) +static void update_icon_name(struct pw_properties *p, bool is_sink) { const char *s, *d = NULL, *bus; @@ -254,7 +254,7 @@ static void update_icon_name(struct pw_properties *p, struct pw_properties *prop bus = pw_properties_get(p, PW_KEY_DEVICE_BUS); - pw_properties_setf(props, PW_KEY_DEVICE_ICON_NAME, + pw_properties_setf(p, PW_KEY_DEVICE_ICON_NAME, "%s%s%s%s", d, s ? s : "", bus ? "-" : "", bus ? bus : ""); } @@ -409,7 +409,7 @@ static struct node *alsa_create_node(struct device *device, uint32_t id, } } if (pw_properties_get(node->props, PW_KEY_DEVICE_ICON_NAME) == NULL) - update_icon_name(node->props, node->props, node->direction == PW_DIRECTION_INPUT); + update_icon_name(node->props, node->direction == PW_DIRECTION_INPUT); node->impl = impl; node->device = device; @@ -607,7 +607,7 @@ static int update_device_props(struct device *device) } if (pw_properties_get(p, PW_KEY_DEVICE_ICON_NAME) == NULL) - update_icon_name(device->props, device->props, true); + update_icon_name(device->props, true); return 1; } diff --git a/src/examples/media-session/bluez-monitor.c b/src/examples/media-session/bluez-monitor.c index 4b0292c99..67768e6e2 100644 --- a/src/examples/media-session/bluez-monitor.c +++ b/src/examples/media-session/bluez-monitor.c @@ -114,6 +114,61 @@ static struct node *bluez5_find_node(struct device *device, uint32_t id) return NULL; } +static void update_icon_name(struct pw_properties *p, bool is_sink) +{ + const char *s, *d = NULL, *bus; + + if ((s = pw_properties_get(p, PW_KEY_DEVICE_FORM_FACTOR))) { + if (strcmp(s, "microphone") == 0) + d = "audio-input-microphone"; + else if (strcmp(s, "webcam") == 0) + d = "camera-web"; + else if (strcmp(s, "computer") == 0) + d = "computer"; + else if (strcmp(s, "handset") == 0) + d = "phone"; + else if (strcmp(s, "portable") == 0) + d = "multimedia-player"; + else if (strcmp(s, "tv") == 0) + d = "video-display"; + else if (strcmp(s, "headset") == 0) + d = "audio-headset"; + else if (strcmp(s, "headphone") == 0) + d = "audio-headphones"; + else if (strcmp(s, "speaker") == 0) + d = "audio-speakers"; + else if (strcmp(s, "hands-free") == 0) + d = "audio-handsfree"; + } + if (!d) + if ((s = pw_properties_get(p, PW_KEY_DEVICE_CLASS))) + if (strcmp(s, "modem") == 0) + d = "modem"; + + if (!d) { + if (is_sink) + d = "audio-card"; + else + d = "audio-input-microphone"; + } + + if ((s = pw_properties_get(p, "device.profile.name")) != NULL) { + if (strstr(s, "analog")) + s = "-analog"; + else if (strstr(s, "iec958")) + s = "-iec958"; + else if (strstr(s, "hdmi")) + s = "-hdmi"; + else + s = NULL; + } + + bus = pw_properties_get(p, PW_KEY_DEVICE_BUS); + + pw_properties_setf(p, PW_KEY_DEVICE_ICON_NAME, + "%s%s%s%s", d, s ? s : "", bus ? "-" : "", bus ? bus : ""); +} + static void bluez5_update_node(struct device *device, struct node *node, const struct spa_device_object_info *info) { @@ -134,6 +189,7 @@ static struct node *bluez5_create_node(struct device *device, uint32_t id, const char *prefix, *str, *profile, *rules; int priority; char tmp[1024]; + bool is_sink; pw_log_debug("new node %u", id); @@ -149,6 +205,13 @@ static struct node *bluez5_create_node(struct device *device, uint32_t id, node->props = pw_properties_new_dict(info->props); + if (pw_properties_get(node->props, PW_KEY_DEVICE_FORM_FACTOR) == NULL) + pw_properties_set(node->props, PW_KEY_DEVICE_FORM_FACTOR, + pw_properties_get(device->props, PW_KEY_DEVICE_FORM_FACTOR)); + if (pw_properties_get(node->props, PW_KEY_DEVICE_BUS) == NULL) + pw_properties_set(node->props, PW_KEY_DEVICE_BUS, + pw_properties_get(device->props, PW_KEY_DEVICE_BUS)); + str = pw_properties_get(device->props, SPA_KEY_DEVICE_DESCRIPTION); if (str == NULL) str = pw_properties_get(device->props, SPA_KEY_DEVICE_NAME); @@ -172,7 +235,8 @@ static struct node *bluez5_create_node(struct device *device, uint32_t id, if (str == NULL) str = pw_properties_get(device->props, SPA_KEY_DEVICE_NAME); - if (strstr(info->factory_name, "sink") != NULL) + is_sink = strstr(info->factory_name, "sink") != NULL; + if (is_sink) prefix = "bluez_output"; else if (strstr(info->factory_name, "source") != NULL) prefix = "bluez_input"; @@ -194,6 +258,8 @@ static struct node *bluez5_create_node(struct device *device, uint32_t id, pw_properties_setf(node->props, PW_KEY_PRIORITY_DRIVER, "%d", priority); pw_properties_setf(node->props, PW_KEY_PRIORITY_SESSION, "%d", priority); } + if (pw_properties_get(node->props, PW_KEY_DEVICE_ICON_NAME) == NULL) + update_icon_name(node->props, is_sink); node->impl = impl; node->device = device; @@ -341,6 +407,10 @@ static int update_device_props(struct device *device) pw_properties_set(p, PW_KEY_DEVICE_NAME, sm_media_session_sanitize_name(tmp, sizeof(tmp), '_', "bluez_card.%s", s)); + + if (pw_properties_get(p, SPA_KEY_DEVICE_ICON_NAME) == NULL) + update_icon_name(p, true); + return 0; }