From 31b2b8ec78198c72bc7e139c5cccd178bd835e72 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Apr 2015 13:17:22 +0200 Subject: [PATCH] linux: Work-around broken battery on the Onda v975w Until https://bugzilla.kernel.org/show_bug.cgi?id=83941 is fixed, this allow to have a bit more information than "0% battery" displayed in the UI. https://bugs.freedesktop.org/show_bug.cgi?id=90214 --- src/linux/integration-test | 27 +++++++++++++++++++++++++++ src/linux/up-device-supply.c | 21 ++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/linux/integration-test b/src/linux/integration-test index 4e5f13e..ad7152a 100755 --- a/src/linux/integration-test +++ b/src/linux/integration-test @@ -802,6 +802,33 @@ class Tests(unittest.TestCase): self.assertEqual(self.get_dbus_display_property('WarningLevel'), UP_DEVICE_LEVEL_NONE) self.stop_daemon() + def test_broken_onda_battery(self): + '''Onda v975w battery: https://bugzilla.kernel.org/show_bug.cgi?id=83941''' + + batc = self.testbed.add_device('power_supply', 'BATC', None, + ['type', 'Battery', + 'capacity', '0', + 'capacity_level', 'Normal', + 'present', '1', + 'energy_full', '0', + 'energy_full_design', '0', + 'energy_now', '5549000', + 'power_now', '97000', + 'voltage_now', '3970000'], []) + + self.start_daemon() + devs = self.proxy.EnumerateDevices() + self.assertEqual(len(devs), 1) + batc_up = devs[0] + + self.assertEqual(self.get_dbus_dev_property(batc_up, 'Percentage'), 100.0) + + self.testbed.set_attribute(batc, 'energy_now', '2774500') + time.sleep(5) + self.assertEqual(int(self.get_dbus_dev_property(batc_up, 'Percentage')), 50) + + self.stop_daemon() + # # libupower-glib tests (through introspection) # diff --git a/src/linux/up-device-supply.c b/src/linux/up-device-supply.c index 5d15083..1f86382 100644 --- a/src/linux/up-device-supply.c +++ b/src/linux/up-device-supply.c @@ -584,6 +584,16 @@ up_device_supply_refresh_battery (UpDeviceSupply *supply, supply->priv->coldplug_units = UP_DEVICE_SUPPLY_COLDPLUG_UNITS_CHARGE; } + /* Fix broken batteries without energy-full information */ + if (energy_full < 0.01 && energy_full_design < 0.01) { + gdouble old_energy_full_design; + + g_object_get (device, "energy-full-design", &old_energy_full_design, NULL); + energy_full_design = MAX(old_energy_full_design, energy); + /* Make following warning quiet */ + energy_full = energy_full_design; + } + /* the last full should not be bigger than the design */ if (energy_full > energy_full_design) g_warning ("energy_full (%f) is greater than energy_full_design (%f)", @@ -679,9 +689,14 @@ up_device_supply_refresh_battery (UpDeviceSupply *supply, if (sysfs_file_exists (native_path, "capacity")) { percentage = sysfs_get_double (native_path, "capacity"); percentage = CLAMP(percentage, 0.0f, 100.0f); - /* for devices which provide capacity, but not {energy,charge}_now */ - if (energy < 0.1f && energy_full > 0.0f) - energy = energy_full * percentage / 100; + /* for devices which provide capacity, but not {energy,charge}_now */ + if (energy < 0.1f && energy_full > 0.0f) { + energy = energy_full * percentage / 100; + } else if (energy > 0.0f && percentage < 0.01) { + /* capacity isn't set but present */ + percentage = 100.0 * energy / energy_full; + percentage = CLAMP(percentage, 0.0f, 100.0f); + } } else if (energy_full > 0.0f) { percentage = 100.0 * energy / energy_full; percentage = CLAMP(percentage, 0.0f, 100.0f);