summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2022-09-02 11:42:24 +0200
committerBastien Nocera <hadess@hadess.net>2022-09-05 17:47:08 +0200
commit778b93a336bef721ddde5f0ab0cb3c1138adbe06 (patch)
tree4e7c9b5007b37e7c79c127fce6e9103d62ac7bff
parentd998510753602a7169e7ffa3d1e33d8c8dc0eddd (diff)
downloadupower-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.c57
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);
}