diff options
author | Benjamin Berg <bberg@redhat.com> | 2022-06-07 16:25:26 +0200 |
---|---|---|
committer | Benjamin Berg <bberg@redhat.com> | 2022-06-21 11:16:01 +0200 |
commit | 6fedd0f20a64b9996226d0a2d26682a95aa7adb2 (patch) | |
tree | 52c0346db216cb7b4f5b4695077f0a3272318dbc | |
parent | ed2d5a25b3f11e2773c47470c4c4f432b04c9984 (diff) | |
download | upower-6fedd0f20a64b9996226d0a2d26682a95aa7adb2.tar.gz |
linux: Use new battery class and drop unused code
This makes the switch. There are a few behaviour changes with regard to
estimations (which hopefully got both simpler and more robust at the
same time).
-rwxr-xr-x | src/linux/integration-test.py | 7 | ||||
-rw-r--r-- | src/linux/up-device-supply.c | 624 | ||||
-rw-r--r-- | src/linux/up-enumerator-udev.c | 12 |
3 files changed, 22 insertions, 621 deletions
diff --git a/src/linux/integration-test.py b/src/linux/integration-test.py index 3b231b4..56deea9 100755 --- a/src/linux/integration-test.py +++ b/src/linux/integration-test.py @@ -766,7 +766,7 @@ class Tests(dbusmock.DBusTestCase): self.stop_daemon() def test_battery_energy_charge_mixed(self): - '''battery which reports current energy, but full charge''' + '''battery which reports both current charge and energy''' self.testbed.add_device('power_supply', 'BAT0', None, ['type', 'Battery', @@ -774,7 +774,8 @@ class Tests(dbusmock.DBusTestCase): 'status', 'Discharging', 'charge_full', '10500000', 'charge_full_design', '11000000', - 'energy_now', '50400000', + 'charge_now', '4200000', + 'energy_now', '9999999', 'voltage_now', '12000000'], []) self.start_daemon() @@ -786,7 +787,7 @@ class Tests(dbusmock.DBusTestCase): self.assertEqual(self.get_dbus_display_property('WarningLevel'), UP_DEVICE_LEVEL_NONE) self.assertEqual(self.get_dbus_dev_property(bat0_up, 'IsPresent'), True) self.assertEqual(self.get_dbus_dev_property(bat0_up, 'State'), UP_DEVICE_STATE_DISCHARGING) - self.assertEqual(self.get_dbus_dev_property(bat0_up, 'Energy'), 50.4) + self.assertAlmostEqual(self.get_dbus_dev_property(bat0_up, 'Energy'), 50.4) self.assertEqual(self.get_dbus_dev_property(bat0_up, 'EnergyFull'), 126.0) self.assertEqual(self.get_dbus_dev_property(bat0_up, 'EnergyFullDesign'), 132.0) self.assertEqual(self.get_dbus_dev_property(bat0_up, 'Voltage'), 12.0) diff --git a/src/linux/up-device-supply.c b/src/linux/up-device-supply.c index 0f2b835..ab50c67 100644 --- a/src/linux/up-device-supply.c +++ b/src/linux/up-device-supply.c @@ -37,38 +37,16 @@ #include "up-device-supply.h" #include "up-common.h" -enum { - PROP_0, - PROP_IGNORE_SYSTEM_PERCENTAGE -}; - -#define UP_DEVICE_SUPPLY_COLDPLUG_UNITS_CHARGE TRUE -#define UP_DEVICE_SUPPLY_COLDPLUG_UNITS_ENERGY FALSE - -/* number of old energy values to keep cached */ -#define UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH 4 - struct UpDeviceSupplyPrivate { gboolean has_coldplug_values; - gboolean coldplug_units; - gdouble *energy_old; - GTimeVal *energy_old_timespec; - guint energy_old_first; - gdouble rate_old; - gint64 fast_repoll_until; - gboolean disable_battery_poll; /* from configuration */ gboolean shown_invalid_voltage_warning; - gboolean ignore_system_percentage; }; G_DEFINE_TYPE_WITH_PRIVATE (UpDeviceSupply, up_device_supply, UP_TYPE_DEVICE) static gboolean up_device_supply_refresh (UpDevice *device, UpRefreshReason reason); -static void up_device_supply_update_poll_frequency (UpDevice *device, - UpDeviceState state, - UpRefreshReason reason); static UpDeviceKind up_device_supply_guess_type (GUdevDevice *native, const char *native_path); @@ -102,21 +80,10 @@ up_device_supply_refresh_line_power (UpDeviceSupply *supply, static void up_device_supply_reset_values (UpDeviceSupply *supply) { - UpDevice *device = UP_DEVICE (supply); - guint i; - supply->priv->has_coldplug_values = FALSE; - supply->priv->coldplug_units = UP_DEVICE_SUPPLY_COLDPLUG_UNITS_ENERGY; - supply->priv->rate_old = 0; - - for (i = 0; i < UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH; ++i) { - supply->priv->energy_old[i] = 0.0f; - supply->priv->energy_old_timespec[i].tv_sec = 0; - } - supply->priv->energy_old_first = 0; /* reset to default */ - g_object_set (device, + g_object_set (supply, "vendor", NULL, "model", NULL, "serial", NULL, @@ -144,41 +111,6 @@ up_device_supply_reset_values (UpDeviceSupply *supply) } /** - * up_device_supply_get_on_battery: - **/ -static gboolean -up_device_supply_get_on_battery (UpDevice *device, gboolean *on_battery) -{ - UpDeviceSupply *supply = UP_DEVICE_SUPPLY (device); - UpDeviceKind type; - UpDeviceState state; - gboolean is_power_supply; - gboolean is_present; - - g_return_val_if_fail (UP_IS_DEVICE_SUPPLY (supply), FALSE); - g_return_val_if_fail (on_battery != NULL, FALSE); - - g_object_get (device, - "type", &type, - "state", &state, - "is-present", &is_present, - "power-supply", &is_power_supply, - NULL); - - if (!is_power_supply) - return FALSE; - if (type != UP_DEVICE_KIND_BATTERY) - return FALSE; - if (state == UP_DEVICE_STATE_UNKNOWN) - return FALSE; - if (!is_present) - return FALSE; - - *on_battery = (state == UP_DEVICE_STATE_DISCHARGING); - return TRUE; -} - -/** * up_device_supply_get_online: **/ static gboolean @@ -205,93 +137,6 @@ up_device_supply_get_online (UpDevice *device, gboolean *online) } /** - * up_device_supply_push_new_energy: - * - * Store the new energy in the list of old energies of the supply, so - * it can be used to determine the energy rate. - */ -static gboolean -up_device_supply_push_new_energy (UpDeviceSupply *supply, gdouble energy) -{ - guint first = supply->priv->energy_old_first; - guint new_position = (first + UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH - 1) % - UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH; - - /* check if the energy value has changed and, if that's the case, - * store the new values in the buffer. */ - if (supply->priv->energy_old[first] != energy) { - supply->priv->energy_old[new_position] = energy; - g_get_current_time (&supply->priv->energy_old_timespec[new_position]); - supply->priv->energy_old_first = new_position; - return TRUE; - } - - return FALSE; -} - -/** - * up_device_supply_calculate_rate: - **/ -static gdouble -up_device_supply_calculate_rate (UpDeviceSupply *supply, gdouble energy) -{ - gdouble rate = 0.0f; - gdouble sum_x = 0.0f; /* sum of the squared times difference */ - GTimeVal now; - guint i; - guint valid_values = 0; - - /* get the time difference from now and use linear regression to determine - * the discharge rate of the battery. */ - g_get_current_time (&now); - - /* store the data on the new energy received */ - up_device_supply_push_new_energy (supply, energy); - - if (energy < 0.1f) - return 0.0f; - - if (supply->priv->energy_old[supply->priv->energy_old_first] < 0.1f) - return 0.0f; - - /* don't use the new point obtained since it may cause instability in - * the estimate */ - i = supply->priv->energy_old_first; - now = supply->priv->energy_old_timespec[i]; - do { - /* only use this value if it seems valid */ - if (supply->priv->energy_old_timespec[i].tv_sec && supply->priv->energy_old[i]) { - /* This is the square of t_i^2 */ - sum_x += (now.tv_sec - supply->priv->energy_old_timespec[i].tv_sec) * - (now.tv_sec - supply->priv->energy_old_timespec[i].tv_sec); - - /* Sum the module of the energy difference */ - rate += fabs ((supply->priv->energy_old_timespec[i].tv_sec - now.tv_sec) * - (energy - supply->priv->energy_old[i])); - valid_values++; - } - - /* get the next element in the circular buffer */ - i = (i + 1) % UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH; - } while (i != supply->priv->energy_old_first); - - /* Check that at least 3 points were involved in computation */ - if (sum_x == 0.0f || valid_values < 3) - return supply->priv->rate_old; - - /* Compute the discharge per hour, and not per second */ - rate /= sum_x / SECONDS_PER_HOUR_F; - - /* if the rate is zero, use the old rate. It will usually happens if no - * data is in the buffer yet. If the rate is too high, i.e. more than, - * 100W don't use it. */ - if (rate == 0.0f || rate > 100.0f) - return supply->priv->rate_old; - - return rate; -} - -/** * up_device_supply_get_string: **/ static gchar * @@ -318,83 +163,6 @@ out: return value; } -/** - * up_device_supply_get_design_voltage: - **/ -static gdouble -up_device_supply_get_design_voltage (UpDeviceSupply *device, - GUdevDevice *native) -{ - gdouble voltage; - gchar *device_type = NULL; - - /* design maximum */ - voltage = g_udev_device_get_sysfs_attr_as_double_uncached (native, "voltage_max_design") / 1000000.0; - if (voltage > 1.00f) { - g_debug ("using max design voltage"); - goto out; - } - - /* design minimum */ - voltage = g_udev_device_get_sysfs_attr_as_double_uncached (native, "voltage_min_design") / 1000000.0; - if (voltage > 1.00f) { - g_debug ("using min design voltage"); - goto out; - } - - /* current voltage */ - voltage = g_udev_device_get_sysfs_attr_as_double_uncached (native, "voltage_present") / 1000000.0; - if (voltage > 1.00f) { - g_debug ("using present voltage"); - goto out; - } - - /* current voltage, alternate form */ - voltage = g_udev_device_get_sysfs_attr_as_double_uncached (native, "voltage_now") / 1000000.0; - if (voltage > 1.00f) { - g_debug ("using present voltage (alternate)"); - goto out; - } - - /* is this a USB device? */ - device_type = up_device_supply_get_string (native, "type"); - if (device_type != NULL && g_ascii_strcasecmp (device_type, "USB") == 0) { - g_debug ("USB device, so assuming 5v"); - voltage = 5.0f; - goto out; - } - - /* no valid value found; display a warning the first time for each - * device */ - if (!device->priv->shown_invalid_voltage_warning) { - device->priv->shown_invalid_voltage_warning = TRUE; - g_warning ("no valid voltage value found for device %s, assuming 10V", - g_udev_device_get_sysfs_path (native)); - } - /* completely guess, to avoid getting zero values */ - g_debug ("no voltage values for device %s, using 10V as approximation", - g_udev_device_get_sysfs_path (native)); - voltage = 10.0f; -out: - g_free (device_type); - return voltage; -} - -static gboolean -up_device_supply_units_changed (UpDeviceSupply *supply, - GUdevDevice *native) -{ - if (supply->priv->coldplug_units == UP_DEVICE_SUPPLY_COLDPLUG_UNITS_CHARGE) - if (g_udev_device_has_sysfs_attr_uncached (native, "charge_now") || - g_udev_device_has_sysfs_attr_uncached (native, "charge_avg")) - return FALSE; - if (supply->priv->coldplug_units == UP_DEVICE_SUPPLY_COLDPLUG_UNITS_ENERGY) - if (g_udev_device_has_sysfs_attr_uncached (native, "energy_now") || - g_udev_device_has_sysfs_attr_uncached (native, "energy_avg")) - return FALSE; - return TRUE; -} - UpDeviceState up_device_supply_get_state (GUdevDevice *native) { @@ -482,283 +250,6 @@ sysfs_get_capacity_level (GUdevDevice *native, } static gboolean -up_device_supply_refresh_battery (UpDeviceSupply *supply, - UpRefreshReason reason) -{ - gchar *technology_native = NULL; - gdouble voltage_design; - UpDeviceState old_state; - UpDeviceState state; - UpDevice *device = UP_DEVICE (supply); - GUdevDevice *native; - gboolean is_present; - gdouble energy; - gdouble energy_full; - gdouble energy_full_design; - gdouble energy_rate; - gdouble capacity = 100.0f; - gdouble percentage = 0.0f; - gdouble voltage; - gint64 time_to_empty; - gint64 time_to_full; - gdouble temp; - int charge_cycles = -1; - gchar *manufacturer = NULL; - gchar *model_name = NULL; - gchar *serial_number = NULL; - guint i; - - native = G_UDEV_DEVICE (up_device_get_native (device)); - - /* have we just been removed? */ - if (g_udev_device_has_sysfs_attr_uncached (native, "present")) { - is_present = g_udev_device_get_sysfs_attr_as_boolean_uncached (native, "present"); - } else { - /* when no present property exists, handle as present */ - is_present = TRUE; - } - g_object_set (device, "is-present", is_present, NULL); - if (!is_present) { - up_device_supply_reset_values (supply); - goto out; - } - - /* get the current charge */ - energy = g_udev_device_get_sysfs_attr_as_double_uncached (native, "energy_now") / 1000000.0; - if (energy < 0.01) - energy = g_udev_device_get_sysfs_attr_as_double_uncached (native, "energy_avg") / 1000000.0; - - /* used to convert A to W later */ - voltage_design = up_device_supply_get_design_voltage (supply, native); - - /* initial values */ - if (!supply->priv->has_coldplug_values || - up_device_supply_units_changed (supply, native)) { - - /* the ACPI spec is bad at defining battery type constants */ - technology_native = up_device_supply_get_string (native, "technology"); - g_object_set (device, "technology", up_convert_device_technology (technology_native), NULL); - - /* get values which may be blank */ - manufacturer = up_device_supply_get_string (native, "manufacturer"); - model_name = up_device_supply_get_string (native, "model_name"); - serial_number = up_device_supply_get_string (native, "serial_number"); - - /* some vendors fill this with binary garbage */ - up_make_safe_string (manufacturer); - up_make_safe_string (model_name); - up_make_safe_string (serial_number); - - g_object_set (device, - "vendor", manufacturer, - "model", model_name, - "serial", serial_number, - "is-rechargeable", TRUE, /* assume true for laptops */ - "has-history", TRUE, - "has-statistics", TRUE, - NULL); - - /* these don't change at runtime */ - energy_full = g_udev_device_get_sysfs_attr_as_double_uncached (native, "energy_full") / 1000000.0; - energy_full_design = g_udev_device_get_sysfs_attr_as_double_uncached (native, "energy_full_design") / 1000000.0; - - /* convert charge to energy */ - if (energy_full < 0.01) { - energy_full = g_udev_device_get_sysfs_attr_as_double_uncached (native, "charge_full") / 1000000.0; - energy_full_design = g_udev_device_get_sysfs_attr_as_double_uncached (native, "charge_full_design") / 1000000.0; - energy_full *= voltage_design; - energy_full_design *= voltage_design; - supply->priv->coldplug_units = UP_DEVICE_SUPPLY_COLDPLUG_UNITS_CHARGE; - } - - /* 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)", - energy_full, energy_full_design); - - /* some systems don't have this */ - if (energy_full < 0.01 && energy_full_design > 0.01) { - g_warning ("correcting energy_full (%f) using energy_full_design (%f)", - energy_full, energy_full_design); - energy_full = energy_full_design; - } - - /* calculate how broken our battery is */ - if (energy_full > 0) { - capacity = (energy_full / energy_full_design) * 100.0f; - if (capacity < 0) - capacity = 0.0; - if (capacity > 100.0) - capacity = 100.0; - } - g_object_set (device, "capacity", capacity, NULL); - - /* we only coldplug once, as these values will never change */ - supply->priv->has_coldplug_values = TRUE; - } else { - /* get the old full */ - g_object_get (device, - "energy-full", &energy_full, - "energy-full-design", &energy_full_design, - NULL); - } - - state = up_device_supply_get_state (native); - - /* this is the new value in uW */ - if (g_udev_device_has_sysfs_attr (native, "power_now")) { - energy_rate = fabs (g_udev_device_get_sysfs_attr_as_double_uncached (native, "power_now") / 1000000.0); - } else { - gdouble charge_full; - - /* convert charge to energy */ - if (energy < 0.01) { - energy = g_udev_device_get_sysfs_attr_as_double_uncached (native, "charge_now") / 1000000.0; - if (energy < 0.01) - energy = g_udev_device_get_sysfs_attr_as_double_uncached (native, "charge_avg") / 1000000.0; - energy *= voltage_design; - } - - charge_full = g_udev_device_get_sysfs_attr_as_double_uncached (native, "charge_full") / 1000000.0; - if (charge_full < 0.01) - charge_full = g_udev_device_get_sysfs_attr_as_double_uncached (native, "charge_full_design") / 1000000.0; - - /* If charge_full exists, then current_now is always reported in uA. - * In the legacy case, where energy only units exist, and power_now isn't present - * current_now is power in uW. */ - energy_rate = fabs (g_udev_device_get_sysfs_attr_as_double_uncached (native, "current_now") / 1000000.0); - if (charge_full != 0) - energy_rate *= voltage_design; - } - - /* some batteries don't update last_full attribute */ - if (energy > energy_full) { - g_warning ("energy %f bigger than full %f", energy, energy_full); - energy_full = energy; - } - - /* present voltage */ - voltage = g_udev_device_get_sysfs_attr_as_double_uncached (native, "voltage_now") / 1000000.0; - if (voltage < 0.01) - voltage = g_udev_device_get_sysfs_attr_as_double_uncached (native, "voltage_avg") / 1000000.0; - - /* ACPI gives out the special 'Ones' value for rate when it's unable - * to calculate the true rate. We should set the rate zero, and wait - * for the BIOS to stabilise. */ - if (energy_rate == 0xffff) - energy_rate = 0; - - /* Ensure less than 300W, above the 240W possible with USB Power Delivery */ - if (energy_rate > 300) - energy_rate = 0; - - /* the hardware reporting failed -- try to calculate this */ - if (energy_rate < 0.01) - energy_rate = up_device_supply_calculate_rate (supply, energy); - - /* get a precise percentage */ - if (!supply->priv->ignore_system_percentage && - g_udev_device_has_sysfs_attr_uncached (native, "capacity")) { - percentage = g_udev_device_get_sysfs_attr_as_double_uncached (native, "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; - } else if (energy_full > 0.0f) { - percentage = 100.0 * energy / energy_full; - percentage = CLAMP(percentage, 0.0f, 100.0f); - } - - /* Some devices report "Not charging" when the battery is full and AC - * power is connected. In this situation we should report fully-charged - * instead of pending-charge. */ - if (state == UP_DEVICE_STATE_PENDING_CHARGE && percentage >= UP_FULLY_CHARGED_THRESHOLD) - state = UP_DEVICE_STATE_FULLY_CHARGED; - - /* if empty, and BIOS does not know what to do */ - if (state == UP_DEVICE_STATE_UNKNOWN && percentage < 1) { - g_warning ("Setting %s state empty as unknown and very low", - g_udev_device_get_sysfs_path (native)); - state = UP_DEVICE_STATE_EMPTY; - } - - /* some batteries give out massive rate values when nearly empty */ - if (energy < 0.1f) - energy_rate = 0.0f; - - /* calculate a quick and dirty time remaining value */ - time_to_empty = 0; - time_to_full = 0; - if (energy_rate > 0) { - if (state == UP_DEVICE_STATE_DISCHARGING) - time_to_empty = 3600 * (energy / energy_rate); - else if (state == UP_DEVICE_STATE_CHARGING) - time_to_full = 3600 * ((energy_full - energy) / energy_rate); - /* TODO: need to factor in battery charge metrics */ - } - - /* check the remaining time is under a set limit, to deal with broken - primary batteries rate */ - if (time_to_empty > (240 * 60 * 60)) /* ten days for discharging */ - time_to_empty = 0; - if (time_to_full > (20 * 60 * 60)) /* 20 hours for charging */ - time_to_full = 0; - - /* get temperature */ - temp = g_udev_device_get_sysfs_attr_as_double_uncached (native, "temp") / 10.0; - - /* charge_cycles is -1 if: - * cycle_count is -1 (unknown) - * cycle_count is 0 (shouldn't be used by conforming implementations) - * cycle_count is absent (unsupported) */ - if (g_udev_device_has_sysfs_attr_uncached (native, "cycle_count")) { - charge_cycles = g_udev_device_get_sysfs_attr_as_int_uncached (native, "cycle_count"); - if (charge_cycles == 0) - charge_cycles = -1; - } - - /* check if the energy value has changed and, if that's the case, - * store the new values in the buffer. */ - if (up_device_supply_push_new_energy (supply, energy)) - supply->priv->rate_old = energy_rate; - - /* we changed state */ - g_object_get (device, "state", &old_state, NULL); - if (old_state != state) { - for (i = 0; i < UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH; ++i) { - supply->priv->energy_old[i] = 0.0f; - supply->priv->energy_old_timespec[i].tv_sec = 0; - - } - supply->priv->energy_old_first = 0; - } - - g_object_set (device, - "energy", energy, - "energy-full", energy_full, - "energy-full-design", energy_full_design, - "energy-rate", energy_rate, - "percentage", percentage, - "state", state, - "voltage", voltage, - "time-to-empty", time_to_empty, - "time-to-full", time_to_full, - "temperature", temp, - "charge-cycles", charge_cycles, - NULL); - - /* Setup unknown poll again if needed */ - up_device_supply_update_poll_frequency (device, state, reason); - -out: - g_free (technology_native); - g_free (manufacturer); - g_free (model_name); - g_free (serial_number); - return TRUE; -} - -static gboolean up_device_supply_refresh_device (UpDeviceSupply *supply, UpRefreshReason reason) { @@ -1026,71 +517,28 @@ up_device_supply_coldplug (UpDevice *device) "power-supply", is_power_supply, NULL); - if (type != UP_DEVICE_KIND_LINE_POWER && - type != UP_DEVICE_KIND_BATTERY) - g_object_set (device, "poll-timeout", UP_DAEMON_SHORT_TIMEOUT, NULL); - else if (type == UP_DEVICE_KIND_BATTERY && - (!supply->priv->disable_battery_poll || !is_power_supply)) + /* Handled by separate battery class */ + if (is_power_supply) + g_assert (type == UP_DEVICE_KIND_LINE_POWER); + + if (type != UP_DEVICE_KIND_LINE_POWER) g_object_set (device, "poll-timeout", UP_DAEMON_SHORT_TIMEOUT, NULL); return TRUE; } -static void -up_device_supply_update_poll_frequency (UpDevice *device, - UpDeviceState state, - UpRefreshReason reason) -{ - UpDeviceSupply *supply = UP_DEVICE_SUPPLY (device); - - if (supply->priv->disable_battery_poll) - return; - - /* We start fast-polling if the reason to update was not a normal POLL - * and one of the following holds true: - * 1. The current stat is unknown; we hope that this is transient - * and re-poll. - * 2. A change occured on a line power supply. This likely means that - * batteries switch between charging/discharging which does not - * always result in a separate uevent. - * - * For simplicity, we do the fast polling for a specific period of time. - * If the reason to do fast-polling was an unknown state, then it would - * also be reasonable to stop as soon as we got a proper state. - */ - if (reason != UP_REFRESH_POLL && - (state == UP_DEVICE_STATE_UNKNOWN || - reason == UP_REFRESH_LINE_POWER)) { - g_debug ("unknown_poll: setting up fast re-poll"); - g_object_set (device, "poll-timeout", UP_DAEMON_UNKNOWN_TIMEOUT, NULL); - supply->priv->fast_repoll_until = g_get_monotonic_time () + UP_DAEMON_UNKNOWN_POLL_TIME * G_USEC_PER_SEC; - - } else if (supply->priv->fast_repoll_until == 0) { - /* Not fast-repolling, no need to check whether to stop */ - - } else if (supply->priv->fast_repoll_until < g_get_monotonic_time ()) { - g_debug ("unknown_poll: stopping fast repoll (giving up)"); - supply->priv->fast_repoll_until = 0; - g_object_set (device, "poll-timeout", UP_DAEMON_SHORT_TIMEOUT, NULL); - } -} - static gboolean up_device_supply_refresh (UpDevice *device, UpRefreshReason reason) { gboolean updated; UpDeviceSupply *supply = UP_DEVICE_SUPPLY (device); UpDeviceKind type; - gboolean is_power_supply = FALSE; g_object_get (device, "type", &type, - "power-supply", &is_power_supply, NULL); if (type == UP_DEVICE_KIND_LINE_POWER) { updated = up_device_supply_refresh_line_power (supply, reason); - } else if (type == UP_DEVICE_KIND_BATTERY && is_power_supply) { - updated = up_device_supply_refresh_battery (supply, reason); } else { updated = up_device_supply_refresh_device (supply, reason); } @@ -1108,22 +556,9 @@ up_device_supply_refresh (UpDevice *device, UpRefreshReason reason) static void up_device_supply_init (UpDeviceSupply *supply) { - UpConfig *config; - supply->priv = up_device_supply_get_instance_private (supply); - /* allocate the stats for the battery charging & discharging */ - supply->priv->energy_old = g_new (gdouble, UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH); - supply->priv->energy_old_timespec = g_new (GTimeVal, UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH); - supply->priv->shown_invalid_voltage_warning = FALSE; - - config = up_config_new (); - /* Seems that we don't get change uevents from the - * kernel on some BIOS types, but if polling - * is disabled in the configuration, do nothing */ - supply->priv->disable_battery_poll = up_config_get_boolean (config, "NoPollBatteries"); - g_object_unref (config); } /** @@ -1140,46 +575,9 @@ up_device_supply_finalize (GObject *object) supply = UP_DEVICE_SUPPLY (object); g_return_if_fail (supply->priv != NULL); - g_free (supply->priv->energy_old); - g_free (supply->priv->energy_old_timespec); - G_OBJECT_CLASS (up_device_supply_parent_class)->finalize (object); } -static void -up_device_supply_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - UpDeviceSupply *supply = UP_DEVICE_SUPPLY (object); - - switch (property_id) { - case PROP_IGNORE_SYSTEM_PERCENTAGE: - supply->priv->ignore_system_percentage = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - } -} - -static void -up_device_supply_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - UpDeviceSupply *supply = UP_DEVICE_SUPPLY (object); - - switch (property_id) { - case PROP_IGNORE_SYSTEM_PERCENTAGE: - g_value_set_flags (value, supply->priv->ignore_system_percentage); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - } -} - /** * up_device_supply_class_init: **/ @@ -1190,17 +588,9 @@ up_device_supply_class_init (UpDeviceSupplyClass *klass) UpDeviceClass *device_class = UP_DEVICE_CLASS (klass); object_class->finalize = up_device_supply_finalize; - object_class->set_property = up_device_supply_set_property; - object_class->get_property = up_device_supply_get_property; - device_class->get_on_battery = up_device_supply_get_on_battery; + device_class->get_online = up_device_supply_get_online; device_class->coldplug = up_device_supply_coldplug; device_class->sibling_discovered = up_device_supply_sibling_discovered; device_class->refresh = up_device_supply_refresh; - - g_object_class_install_property (object_class, PROP_IGNORE_SYSTEM_PERCENTAGE, - g_param_spec_boolean ("ignore-system-percentage", - "Ignore system percentage", - "Ignore system provided battery percentage", - FALSE, G_PARAM_READWRITE)); } diff --git a/src/linux/up-enumerator-udev.c b/src/linux/up-enumerator-udev.c index 917747a..9e52d15 100644 --- a/src/linux/up-enumerator-udev.c +++ b/src/linux/up-enumerator-udev.c @@ -26,6 +26,7 @@ #include "up-enumerator-udev.h" #include "up-device-supply.h" +#include "up-device-supply-battery.h" #include "up-device-hid.h" #include "up-device-wup.h" @@ -93,11 +94,20 @@ device_new (UpEnumeratorUdev *self, GUdevDevice *native) subsys = g_udev_device_get_subsystem (native); if (g_strcmp0 (subsys, "power_supply") == 0) { - return g_initable_new (UP_TYPE_DEVICE_SUPPLY, NULL, NULL, + UpDevice *device; + + device = g_initable_new (UP_TYPE_DEVICE_SUPPLY_BATTERY, NULL, NULL, "daemon", daemon, "native", native, "ignore-system-percentage", GPOINTER_TO_INT (is_macbook (NULL)), NULL); + if (device) + return device; + + return g_initable_new (UP_TYPE_DEVICE_SUPPLY, NULL, NULL, + "daemon", daemon, + "native", native, + NULL); } else if (g_strcmp0 (subsys, "tty") == 0) { return g_initable_new (UP_TYPE_DEVICE_WUP, NULL, NULL, |