summaryrefslogtreecommitdiffstats
path: root/source/a/upower/patches/linux-Properly-detect-bluetooth-mice-and-keyboards-t.patch
blob: 55de33b7d38f9112941efbfe13ff13abac600a08 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
From 6c706ff03365e462e1b076155428decbed0f55c6 Mon Sep 17 00:00:00 2001
From: Marc Deslauriers <marc.deslauriers@ubuntu.com>
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