Description: Add support for batteries on HID devices HID keyboards can be attached via Bluetooth or USB, but are in a separate class from both. Upower will reach too far up the ownership chain, and won't be able to detect the input device. As a result, keyboards will show up as the main battery. . This patch adds support for creating a chain of classes to look for input data, and places "hid" in front of "bluetooth". . upower (0.99.1-3.1) unstable; urgency=medium . * Non-maintainer upload. * Add support for HID keyboards Author: Sean Cross --- upower-0.99.1.orig/src/linux/up-device-supply.c +++ upower-0.99.1/src/linux/up-device-supply.c @@ -902,6 +902,39 @@ up_device_supply_poll_unknown_battery (U return FALSE; } +static gchar * +up_device_get_input_path (GUdevDevice *native, const gchar *type) +{ + GUdevDevice *dev; + gchar *input_path = NULL; + const gchar *device_path = NULL; + GError *error = NULL; + GDir *dir = NULL; + const gchar *file; + + /* Detect if the battery comes from bluetooth keyboard or mouse. */ + dev = g_udev_device_get_parent_with_subsystem (native, type, NULL); + if (dev != NULL) { + device_path = g_udev_device_get_sysfs_path (dev); + 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; + } + } + g_dir_close (dir); + } else { + g_warning ("Can not open folder %s: %s", device_path, error->message); + g_error_free (error); + } + g_object_unref (dev); + } + + return input_path; +} + /** * up_device_supply_coldplug: * @@ -912,10 +945,8 @@ up_device_supply_coldplug (UpDevice *dev { UpDeviceSupply *supply = UP_DEVICE_SUPPLY (device); gboolean ret = FALSE; - GUdevDevice *bluetooth; GUdevDevice *native; const gchar *file; - const gchar *device_path = NULL; const gchar *native_path; const gchar *scope; gchar *device_type = NULL; @@ -959,43 +990,32 @@ up_device_supply_coldplug (UpDevice *dev type = UP_DEVICE_KIND_LINE_POWER; } else if (g_ascii_strcasecmp (device_type, "battery") == 0) { - /* 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; + int i; + const char *classes[] = {"hid", "bluetooth"}; + int num_classes = sizeof(classes) / sizeof(*classes); + + for (i = 0; i < num_classes && type == UP_DEVICE_KIND_UNKNOWN; i++) { + + input_path = up_device_get_input_path (native, classes[i]); + + if (input_path != NULL) { + if ((dir = g_dir_open (input_path, 0, &error))) { + while ((file = g_dir_read_name (dir))) { + /* Check if it is a mouse device. */ + if (g_str_has_prefix (file, "mouse")) { + type = UP_DEVICE_KIND_MOUSE; + break; + } } + g_dir_close (dir); + } else { + g_warning ("Can not open folder %s: %s", input_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_object_unref (bluetooth); - } - - if (input_path != NULL) { - if ((dir = g_dir_open (input_path, 0, &error))) { - while ((file = g_dir_read_name (dir))) { - /* Check if it is a mouse device. */ - if (g_str_has_prefix (file, "mouse")) { - type = UP_DEVICE_KIND_MOUSE; - break; - } + g_free (input_path); + if (type == UP_DEVICE_KIND_UNKNOWN) { + type = UP_DEVICE_KIND_KEYBOARD; } - g_dir_close (dir); - } else { - g_warning ("Can not open folder %s: %s", input_path, error->message); - g_error_free (error); - } - g_free (input_path); - if (type == UP_DEVICE_KIND_UNKNOWN) { - type = UP_DEVICE_KIND_KEYBOARD; } }