summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2022-06-07 16:25:26 +0200
committerBenjamin Berg <bberg@redhat.com>2022-06-21 11:16:01 +0200
commit6fedd0f20a64b9996226d0a2d26682a95aa7adb2 (patch)
tree52c0346db216cb7b4f5b4695077f0a3272318dbc
parented2d5a25b3f11e2773c47470c4c4f432b04c9984 (diff)
downloadupower-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-xsrc/linux/integration-test.py7
-rw-r--r--src/linux/up-device-supply.c624
-rw-r--r--src/linux/up-enumerator-udev.c12
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,