diff options
author | Bastien Nocera <hadess@hadess.net> | 2022-09-02 11:42:24 +0200 |
---|---|---|
committer | Bastien Nocera <hadess@hadess.net> | 2022-09-05 17:47:08 +0200 |
commit | 778b93a336bef721ddde5f0ab0cb3c1138adbe06 (patch) | |
tree | 4e7c9b5007b37e7c79c127fce6e9103d62ac7bff | |
parent | d998510753602a7169e7ffa3d1e33d8c8dc0eddd (diff) | |
download | upower-778b93a336bef721ddde5f0ab0cb3c1138adbe06.tar.gz |
linux: Hide duplicate Logitech Bluetooth devices
A lot of newer Logitech devices support both the BATT Bluetooth LE
service as well the HID++ protocol. This advertises 2 separate battery
interfaces, one HID++ one through the kernel, one BATT one through
BlueZ.
Avoid confusing UIs and hide the Bluetooth battery from the interface by
checking for duplicates each time a new device is added.
Closes: #166
-rw-r--r-- | src/linux/up-backend.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/linux/up-backend.c b/src/linux/up-backend.c index aa7c769..8853b0c 100644 --- a/src/linux/up-backend.c +++ b/src/linux/up-backend.c @@ -54,6 +54,8 @@ static void up_backend_finalize (GObject *object); #define LOGIND_DBUS_PATH "/org/freedesktop/login1" #define LOGIND_DBUS_INTERFACE "org.freedesktop.login1.Manager" +#define BDADDR_STR_LEN 17 + struct UpBackendPrivate { UpDaemon *daemon; @@ -116,6 +118,59 @@ up_backend_uevent_signal_handler_cb (GUdevClient *client, const gchar *action, } } +static UpDevice * +find_duplicate_device (UpBackend *backend, + UpDevice *device) +{ + gboolean other_device_is_bluez = !UP_IS_DEVICE_BLUEZ (device); + GPtrArray *array; + g_autofree char *serial = NULL; + UpDevice *ret = NULL; + guint i; + + g_object_get (G_OBJECT (device), "serial", &serial, NULL); + + array = up_device_list_get_array (backend->priv->device_list); + for (i = 0; i < array->len; i++) { + g_autofree char *s = NULL; + UpDevice *d; + + d = UP_DEVICE (g_ptr_array_index (array, i)); + if (UP_IS_DEVICE_BLUEZ (d) != other_device_is_bluez) + continue; + g_object_get (G_OBJECT (d), "serial", &s, NULL); + if (s && g_ascii_strncasecmp (s, serial, BDADDR_STR_LEN) == 0) { + ret = g_object_ref (d); + break; + } + } + g_ptr_array_unref (array); + + return ret; +} + +static void +update_duplicate_bluez_device (UpBackend *backend, + UpDevice *added_device) +{ + g_autoptr(UpDevice) other_device = NULL; + UpDevice *bluez_device = NULL; + g_autofree char *name = NULL; + g_autofree char *serial = NULL; + + other_device = find_duplicate_device (backend, added_device); + if (!other_device) + return; + bluez_device = UP_IS_DEVICE_BLUEZ (added_device) ? + added_device : other_device; + g_object_bind_property (bluez_device, "model", + other_device, "model", + G_BINDING_SYNC_CREATE); + g_object_get (G_OBJECT (bluez_device), "serial", &serial, NULL); + up_device_unregister (bluez_device); + g_debug ("Hiding duplicate BlueZ device %s", serial); +} + static gboolean is_interesting_iface_proxy (GDBusProxy *interface_proxy) { @@ -210,6 +265,7 @@ bluez_interface_added (GDBusObjectManager *manager, NULL); if (device) { g_debug ("emitting device-added: %s", g_dbus_object_get_object_path (bus_object)); + update_duplicate_bluez_device (backend, device); g_signal_emit (backend, signals[SIGNAL_DEVICE_ADDED], 0, device); } } @@ -303,6 +359,7 @@ static void udev_device_added_cb (UpBackend *backend, UpDevice *device) { g_debug ("Got new device from udev enumerator: %p", device); + update_duplicate_bluez_device (backend, device); g_signal_emit (backend, signals[SIGNAL_DEVICE_ADDED], 0, device); } |