From 6c706ff03365e462e1b076155428decbed0f55c6 Mon Sep 17 00:00:00 2001 From: Marc Deslauriers Date: Mon, 4 May 2015 19:31:31 -0400 Subject: [PATCH] linux: Properly detect bluetooth mice and keyboards that are HID devices https://bugs.freedesktop.org/show_bug.cgi?id=90222 --- src/linux/integration-test | 41 +++++++++++++++++++++++++++++++++++++ src/linux/up-device-supply.c | 48 ++++++++++++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 17 deletions(-) diff --git a/src/linux/integration-test b/src/linux/integration-test index ad7152a..b83f80d 100755 --- a/src/linux/integration-test +++ b/src/linux/integration-test @@ -761,6 +761,47 @@ class Tests(unittest.TestCase): self.assertEqual(self.get_dbus_dev_property(mb1_up, 'Percentage'), 30) self.assertEqual(self.get_dbus_dev_property(mb1_up, 'PowerSupply'), False) + def test_bluetooth_hid_mouse(self): + '''bluetooth HID mouse battery''' + + self.testbed.add_device('hid', + 'usb1/bluetooth/hci0/hci0:01', + None, + [], []) + + self.testbed.add_device( + 'input', + 'usb1/bluetooth/hci0/hci0:01/input/input2/mouse3', + None, + [], ['DEVNAME', 'input/mouse3', 'ID_INPUT_MOUSE', '1']) + + self.testbed.add_device( + 'power_supply', + 'usb1/bluetooth/hci0/hci0:01/1/power_supply/hid-00:11:22:33:44:55-battery', + None, + ['type', 'Battery', + 'scope', 'Device', + 'present', '1', + 'online', '1', + 'status', 'Discharging', + 'capacity', '30', + 'model_name', 'Fancy BT mouse'], + []) + + self.start_daemon() + devs = self.proxy.EnumerateDevices() + self.assertEqual(len(devs), 1) + mousebat0_up = devs[0] + + self.assertEqual(self.get_dbus_dev_property(mousebat0_up, 'Model'), 'Fancy BT mouse') + self.assertEqual(self.get_dbus_dev_property(mousebat0_up, 'Percentage'), 30) + self.assertEqual(self.get_dbus_dev_property(mousebat0_up, 'PowerSupply'), False) + # 5 == mouse + self.assertEqual(self.get_dbus_dev_property(mousebat0_up, 'Type'), 5) + self.assertEqual(self.get_dbus_property('OnBattery'), False) + self.assertEqual(self.get_dbus_display_property('WarningLevel'), UP_DEVICE_LEVEL_NONE) + self.stop_daemon() + def test_bluetooth_keyboard(self): '''bluetooth keyboard battery''' diff --git a/src/linux/up-device-supply.c b/src/linux/up-device-supply.c index 1f86382..b96080b 100644 --- a/src/linux/up-device-supply.c +++ b/src/linux/up-device-supply.c @@ -932,9 +932,12 @@ up_device_supply_coldplug (UpDevice *device) const gchar *scope; gchar *device_type = NULL; gchar *input_path = NULL; + gchar *subdir = NULL; GDir *dir = NULL; GError *error = NULL; UpDeviceKind type = UP_DEVICE_KIND_UNKNOWN; + guint i; + const char *class[] = { "hid", "bluetooth" }; up_device_supply_reset_values (supply); @@ -970,28 +973,39 @@ up_device_supply_coldplug (UpDevice *device) if (g_ascii_strcasecmp (device_type, "mains") == 0) { type = UP_DEVICE_KIND_LINE_POWER; } else if (g_ascii_strcasecmp (device_type, "battery") == 0) { + for (i = 0; i < G_N_ELEMENTS(class) && type == UP_DEVICE_KIND_UNKNOWN; i++) { + /* Detect if the battery comes from bluetooth keyboard or mouse. */ + bluetooth = g_udev_device_get_parent_with_subsystem (native, class[i], NULL); + if (bluetooth != NULL) { + device_path = g_udev_device_get_sysfs_path (bluetooth); + + /* There may be an extra subdirectory here */ + subdir = g_build_filename (device_path, "input", NULL); + if (!g_file_test (subdir, G_FILE_TEST_IS_DIR)) { + g_free(subdir); + subdir = g_strdup (device_path); + } - /* Detect if the battery comes from bluetooth keyboard or mouse. */ - bluetooth = g_udev_device_get_parent_with_subsystem (native, "bluetooth", NULL); - if (bluetooth != NULL) { - device_path = g_udev_device_get_sysfs_path (bluetooth); - if ((dir = g_dir_open (device_path, 0, &error))) { - while ((file = g_dir_read_name (dir))) { - /* Check if it is an input device. */ - if (g_str_has_prefix (file, "input")) { - input_path = g_build_filename (device_path, file, NULL); - break; + if ((dir = g_dir_open (subdir, 0, &error))) { + while ((file = g_dir_read_name (dir))) { + /* Check if it is an input device. */ + if (g_str_has_prefix (file, "input")) { + input_path = g_build_filename (subdir, file, NULL); + break; + } } + g_dir_close (dir); + } else { + g_warning ("Can not open folder %s: %s", device_path, error->message); + g_error_free (error); } - g_dir_close (dir); - } else { - g_warning ("Can not open folder %s: %s", device_path, error->message); - g_error_free (error); + g_free (subdir); + g_object_unref (bluetooth); } - g_object_unref (bluetooth); - } - if (input_path != NULL) { + if (input_path == NULL) + continue; + if ((dir = g_dir_open (input_path, 0, &error))) { while ((file = g_dir_read_name (dir))) { /* Check if it is a mouse device. */ -- 2.6.3