[PATCH] up-device-supply: add conditions to workaround bugged firmware to compute "Fully charged" status

Charles-Antoine Couret charles-antoine.couret at essensium.com
Tue Jun 19 07:38:24 UTC 2018


Some firmware like on Lenovo E560 never sends "fully charged" status.
The idea is to consider the situation: a battery without energy consumption,
in discharging mode but with AC power plugged is fully charged.

According to kernel's Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=193061
the fix should be in userspace.

Signed-off-by: Charles-Antoine Couret <charles-antoine.couret at essensium.com>
---
 src/linux/up-device-supply.c | 57 ++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/src/linux/up-device-supply.c b/src/linux/up-device-supply.c
index f6b4b55..1b14828 100644
--- a/src/linux/up-device-supply.c
+++ b/src/linux/up-device-supply.c
@@ -530,6 +530,37 @@ sysfs_get_capacity_level (const char    *native_path,
 	return ret;
 }
 
+static gboolean
+up_device_has_ac (UpDeviceSupply *supply,
+		  gboolean *ac_online)
+{
+	gboolean has_ac = FALSE;
+	gboolean online;
+	UpDeviceList *devices_list;
+	GPtrArray *devices;
+	UpDevice *device = UP_DEVICE (supply);
+	UpDaemon *daemon;
+	guint i;
+
+	daemon = up_device_get_daemon (device);
+
+	devices_list = up_daemon_get_device_list (daemon);
+	devices = up_device_list_get_array (devices_list);
+	for (i=0; i < devices->len; i++) {
+		if (up_device_get_online ((UpDevice *) g_ptr_array_index (devices, i), &online)) {
+		       has_ac = TRUE;
+			if (online) {
+				*ac_online = TRUE;
+			}
+			break;
+		}
+	}
+	g_ptr_array_unref (devices);
+	g_object_unref (devices_list);
+
+	return has_ac;
+}
+
 static RefreshResult
 up_device_supply_refresh_battery (UpDeviceSupply *supply,
 				  UpDeviceState  *out_state)
@@ -559,8 +590,6 @@ up_device_supply_refresh_battery (UpDeviceSupply *supply,
 	gboolean ac_online = FALSE;
 	gboolean has_ac = FALSE;
 	gboolean online;
-	UpDeviceList *devices_list;
-	GPtrArray *devices;
 	guint i;
 
 	native = G_UDEV_DEVICE (up_device_get_native (device));
@@ -698,6 +727,13 @@ up_device_supply_refresh_battery (UpDeviceSupply *supply,
 			energy_rate *= voltage_design;
 	}
 
+	/* some firmware are bugged and never send "Fully charged status"
+	 * We can consider in that condition: battery discharging without energy consumption
+	 * + AC power plugged is in fact fully charged */
+	has_ac = up_device_has_ac (supply, &ac_online);
+	if (has_ac && ac_online && !energy_rate && state == UP_DEVICE_STATE_DISCHARGING)
+		state = UP_DEVICE_STATE_FULLY_CHARGED;
+
 	/* some batteries don't update last_full attribute */
 	if (energy > energy_full) {
 		g_warning ("energy %f bigger than full %f", energy, energy_full);
@@ -739,23 +775,6 @@ up_device_supply_refresh_battery (UpDeviceSupply *supply,
 	 * sitting there half full doing nothing: try to guess a state */
 	if (state == UP_DEVICE_STATE_UNKNOWN && supply->priv->is_power_supply) {
 		daemon = up_device_get_daemon (device);
-
-		/* If we have any online AC, assume charging, otherwise
-		 * discharging */
-		devices_list = up_daemon_get_device_list (daemon);
-		devices = up_device_list_get_array (devices_list);
-		for (i=0; i < devices->len; i++) {
-			if (up_device_get_online ((UpDevice *) g_ptr_array_index (devices, i), &online)) {
-			       has_ac = TRUE;
-				if (online) {
-					ac_online = TRUE;
-				}
-				break;
-			}
-		}
-		g_ptr_array_unref (devices);
-		g_object_unref (devices_list);
-
 		if (has_ac) {
 			if (ac_online) {
 				if (percentage > UP_DEVICE_SUPPLY_CHARGED_THRESHOLD)
-- 
2.17.1



More information about the devkit-devel mailing list