diff options
author | Richard Hughes <richard@hughsie.com> | 2008-08-09 14:27:32 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2008-08-09 14:27:32 +0100 |
commit | 918c35586bf257d316b0dfc6c0822a9c9c142f17 (patch) | |
tree | 9bc33b487f1024c3995168baf746f84295087ac1 | |
parent | 6a498f04873034cc856c02870e7ed0f18fe2094d (diff) | |
download | upower-918c35586bf257d316b0dfc6c0822a9c9c142f17.tar.gz |
refactor out DkpDevice and DkpSupply so we can add another type of device without a metric ton of copy and paste
-rw-r--r-- | doc/Makefile.am | 2 | ||||
-rw-r--r-- | doc/dbus/Makefile.am | 4 | ||||
-rw-r--r-- | doc/devkit-power-docs.xml | 2 | ||||
-rw-r--r-- | src/Makefile.am | 12 | ||||
-rw-r--r-- | src/dkp-daemon.c | 75 | ||||
-rw-r--r-- | src/dkp-daemon.h | 12 | ||||
-rw-r--r-- | src/dkp-device.c | 576 | ||||
-rw-r--r-- | src/dkp-device.h | 55 | ||||
-rw-r--r-- | src/dkp-source.c | 991 | ||||
-rw-r--r-- | src/dkp-source.h | 79 | ||||
-rw-r--r-- | src/dkp-supply.c | 520 | ||||
-rw-r--r-- | src/dkp-supply.h | 56 | ||||
-rw-r--r-- | src/org.freedesktop.DeviceKit.Power.Device.xml (renamed from src/org.freedesktop.DeviceKit.Power.Source.xml) | 4 | ||||
-rw-r--r-- | tools/.gitignore | 1 | ||||
-rw-r--r-- | tools/Makefile.am | 8 | ||||
-rw-r--r-- | tools/dkp-client-device.c | 2 |
16 files changed, 1242 insertions, 1157 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am index 9953167..5d5a83f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -53,7 +53,7 @@ content_files = \ man/devkit-power-daemon.xml \ man/DeviceKit-power.xml \ dbus/org.freedesktop.DeviceKit.Power.ref.xml \ - dbus/org.freedesktop.DeviceKit.Power.Source.ref.xml \ + dbus/org.freedesktop.DeviceKit.Power.Device.ref.xml \ $(NULL) # Images to copy into HTML directory diff --git a/doc/dbus/Makefile.am b/doc/dbus/Makefile.am index d2685f4..c8511ac 100644 --- a/doc/dbus/Makefile.am +++ b/doc/dbus/Makefile.am @@ -1,11 +1,11 @@ -all : org.freedesktop.DeviceKit.Power.ref.xml org.freedesktop.DeviceKit.Power.Source.ref.xml +all : org.freedesktop.DeviceKit.Power.ref.xml org.freedesktop.DeviceKit.Power.Device.ref.xml org.freedesktop.DeviceKit.Power.ref.xml : $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.xml $(top_srcdir)/doc/dbus/spec-to-docbook.xsl echo "<?xml version=\"1.0\"?>""<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\" \"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">" > $@ $(XSLTPROC) $(top_srcdir)/doc/dbus/spec-to-docbook.xsl $< | tail -n +2 >> $@ -org.freedesktop.DeviceKit.Power.Source.ref.xml : $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.Source.xml $(top_srcdir)/doc/dbus/spec-to-docbook.xsl +org.freedesktop.DeviceKit.Power.Device.ref.xml : $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.Device.xml $(top_srcdir)/doc/dbus/spec-to-docbook.xsl echo "<?xml version=\"1.0\"?>""<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\" \"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">" > $@ $(XSLTPROC) $(top_srcdir)/doc/dbus/spec-to-docbook.xsl $< | tail -n +2 >> $@ diff --git a/doc/devkit-power-docs.xml b/doc/devkit-power-docs.xml index 6af1211..5c6e957 100644 --- a/doc/devkit-power-docs.xml +++ b/doc/devkit-power-docs.xml @@ -64,7 +64,7 @@ </para> </partintro> <xi:include href="dbus/org.freedesktop.DeviceKit.Power.ref.xml"/> - <xi:include href="dbus/org.freedesktop.DeviceKit.Power.Source.ref.xml"/> + <xi:include href="dbus/org.freedesktop.DeviceKit.Power.Device.ref.xml"/> </reference> <reference id="tools-fileformats"> diff --git a/src/Makefile.am b/src/Makefile.am index 073bb12..28a9cba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,7 @@ DEVKIT_POWER_LIBS = $(top_builddir)/libdevkit-power/libdevkit-power.la BUILT_SOURCES = \ dkp-daemon-glue.h \ - dkp-source-glue.h \ + dkp-device-glue.h \ dkp-marshal.h dkp-marshal.c dkp-marshal.h: dkp-marshal.list @@ -33,19 +33,19 @@ dkp-marshal.c: dkp-marshal.list dkp-daemon-glue.h: org.freedesktop.DeviceKit.Power.xml Makefile.am dbus-binding-tool --prefix=dkp_daemon --mode=glib-server --output=dkp-daemon-glue.h org.freedesktop.DeviceKit.Power.xml -dkp-source-glue.h: org.freedesktop.DeviceKit.Power.Source.xml Makefile.am - dbus-binding-tool --prefix=dkp_source --mode=glib-server --output=dkp-source-glue.h org.freedesktop.DeviceKit.Power.Source.xml +dkp-device-glue.h: org.freedesktop.DeviceKit.Power.Device.xml Makefile.am + dbus-binding-tool --prefix=dkp_device --mode=glib-server --output=dkp-device-glue.h org.freedesktop.DeviceKit.Power.Device.xml libexec_PROGRAMS = devkit-power-daemon dbusifdir = $(datadir)/dbus-1/interfaces -dbusif_DATA = org.freedesktop.DeviceKit.Power.xml org.freedesktop.DeviceKit.Power.Source.xml +dbusif_DATA = org.freedesktop.DeviceKit.Power.xml org.freedesktop.DeviceKit.Power.Device.xml devkit_power_daemon_SOURCES = \ dkp-daemon.h dkp-daemon.c \ dkp-device.h dkp-device.c \ dkp-device-list.h dkp-device-list.c \ - dkp-source.h dkp-source.c \ + dkp-supply.h dkp-supply.c \ dkp-history.h dkp-history.c \ sysfs-utils.h sysfs-utils.c \ main.c \ @@ -85,7 +85,7 @@ CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = \ org.freedesktop.DeviceKit.Power.xml \ - org.freedesktop.DeviceKit.Power.Source.xml \ + org.freedesktop.DeviceKit.Power.Device.xml \ dkp-marshal.list \ 95-devkit-power.rules \ $(service_in_files) \ diff --git a/src/dkp-daemon.c b/src/dkp-daemon.c index 1e551c8..114b3ac 100644 --- a/src/dkp-daemon.c +++ b/src/dkp-daemon.c @@ -34,7 +34,7 @@ #include "dkp-debug.h" #include "dkp-daemon.h" #include "dkp-device.h" -#include "dkp-source.h" +#include "dkp-supply.h" #include "dkp-device-list.h" #include "dkp-daemon-glue.h" @@ -76,7 +76,7 @@ static gboolean dkp_daemon_get_low_battery_local (DkpDaemon *daemon); G_DEFINE_TYPE (DkpDaemon, dkp_daemon, G_TYPE_OBJECT) -#define DKP_DAEMON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_SOURCE_TYPE_DAEMON, DkpDaemonPrivate)) +#define DKP_DAEMON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_TYPE_DAEMON, DkpDaemonPrivate)) /** * dkp_daemon_error_quark: @@ -85,16 +85,12 @@ GQuark dkp_daemon_error_quark (void) { static GQuark ret = 0; - - if (ret == 0) { + if (ret == 0) ret = g_quark_from_static_string ("dkp_daemon_error"); - } - return ret; } #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - /** * dkp_daemon_error_get_type: **/ @@ -127,7 +123,7 @@ dkp_daemon_constructor (GType type, guint n_construct_properties, GObjectConstru DkpDaemon *daemon; DkpDaemonClass *klass; - klass = DKP_DAEMON_CLASS (g_type_class_peek (DKP_SOURCE_TYPE_DAEMON)); + klass = DKP_DAEMON_CLASS (g_type_class_peek (DKP_TYPE_DAEMON)); daemon = DKP_DAEMON (G_OBJECT_CLASS (dkp_daemon_parent_class)->constructor (type, n_construct_properties, construct_properties)); return G_OBJECT (daemon); } @@ -190,7 +186,7 @@ dkp_daemon_class_init (DkpDaemonClass *klass) g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - dbus_g_object_type_install_info (DKP_SOURCE_TYPE_DAEMON, &dbus_glib_dkp_daemon_object_info); + dbus_g_object_type_install_info (DKP_TYPE_DAEMON, &dbus_glib_dkp_daemon_object_info); dbus_g_error_domain_register (DKP_DAEMON_ERROR, NULL, DKP_DAEMON_TYPE_ERROR); } @@ -308,7 +304,7 @@ gpk_daemon_dbus_filter (DBusConnection *connection, DBusMessage *message, void * return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static void gpk_daemon_device_add (DkpDaemon *daemon, DevkitDevice *d, gboolean emit_event); +static gboolean gpk_daemon_device_add (DkpDaemon *daemon, DevkitDevice *d, gboolean emit_event); static void gpk_daemon_device_remove (DkpDaemon *daemon, DevkitDevice *d); /** @@ -416,13 +412,45 @@ gpk_daemon_device_went_away (gpointer user_data, GObject *_device) dkp_device_list_remove (daemon->priv->list, device); } +#include "dkp-supply.h" + +/** + * gpk_daemon_device_get: + **/ +static DkpDevice * +gpk_daemon_device_get (DevkitDevice *d) +{ + const gchar *type; + const gchar *subsys; + const gchar *native_path; + DkpDevice *device = NULL; + + subsys = devkit_device_get_subsystem (d); + if (strcmp (subsys, "power_supply") == 0) { + /* always add */ + device = DKP_DEVICE (dkp_supply_new ()); + } else if (strcmp (subsys, "usb") == 0) { + /* see if this is a CSR mouse or keyboard */ + type = devkit_device_get_property (d, "ID_BATTERY_TYPE"); + if (type != NULL) + //device = DKP_DEVICE (dkp_csr_new ()); + dkp_warning ("should add %s !!", devkit_device_get_native_path (d)); + } else { + native_path = devkit_device_get_native_path (d); + dkp_warning ("native path %s (%s) ignoring", native_path, subsys); + } + + return device; +} + /** * gpk_daemon_device_add: **/ -static void +static gboolean gpk_daemon_device_add (DkpDaemon *daemon, DevkitDevice *d, gboolean emit_event) { DkpDevice *device; + gboolean ret = FALSE; /* does device exist in db? */ device = dkp_device_list_lookup (daemon->priv->list, d); @@ -431,12 +459,21 @@ gpk_daemon_device_add (DkpDaemon *daemon, DevkitDevice *d, gboolean emit_event) dkp_debug ("treating add event as change event on %s", dkp_device_get_object_path (device)); gpk_daemon_device_changed (daemon, d, FALSE); } else { - device = dkp_device_new (daemon, d); - if (device != NULL) { + /* get the right sort of device */ + device = gpk_daemon_device_get (d); + if (device == NULL) { + dkp_debug ("ignoring add event on %s", devkit_device_get_native_path (d)); + goto out; + } + + /* coldplug */ + ret = dkp_device_coldplug (device, daemon, d); + + /* only if coldplug succeeded */ + if (ret) { /* only take a weak ref; the device will stay on the bus until - * it's unreffed. So if we ref it, it'll never go away. Stupid - * dbus-glib, no cookie for you. + * it's unreffed. So if we ref it, it'll never go away. */ g_object_weak_ref (G_OBJECT (device), gpk_daemon_device_went_away, daemon); dkp_device_list_insert (daemon->priv->list, d, device); @@ -445,9 +482,12 @@ gpk_daemon_device_add (DkpDaemon *daemon, DevkitDevice *d, gboolean emit_event) dkp_device_get_object_path (device)); } } else { - dkp_debug ("ignoring add event on %s", devkit_device_get_native_path (d)); + g_object_unref (device); + dkp_debug ("coldplugging failed: %s", devkit_device_get_native_path (d)); } } +out: + return ret; } /** @@ -599,7 +639,7 @@ dkp_daemon_new (void) GList *devices; GList *l; - daemon = DKP_DAEMON (g_object_new (DKP_SOURCE_TYPE_DAEMON, NULL)); + daemon = DKP_DAEMON (g_object_new (DKP_TYPE_DAEMON, NULL)); daemon->priv->list = dkp_device_list_new (); if (!gpk_daemon_register_power_daemon (DKP_DAEMON (daemon))) { @@ -844,3 +884,4 @@ out: polkit_caller_unref (pk_caller); return TRUE; } + diff --git a/src/dkp-daemon.h b/src/dkp-daemon.h index 36afdf9..d779086 100644 --- a/src/dkp-daemon.h +++ b/src/dkp-daemon.h @@ -27,12 +27,12 @@ G_BEGIN_DECLS -#define DKP_SOURCE_TYPE_DAEMON (dkp_daemon_get_type ()) -#define DKP_DAEMON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_SOURCE_TYPE_DAEMON, DkpDaemon)) -#define DKP_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_SOURCE_TYPE_DAEMON, DkpDaemonClass)) -#define DKP_IS_DAEMON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_SOURCE_TYPE_DAEMON)) -#define DKP_IS_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_SOURCE_TYPE_DAEMON)) -#define DKP_DAEMON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_SOURCE_TYPE_DAEMON, DkpDaemonClass)) +#define DKP_TYPE_DAEMON (dkp_daemon_get_type ()) +#define DKP_DAEMON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_TYPE_DAEMON, DkpDaemon)) +#define DKP_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_TYPE_DAEMON, DkpDaemonClass)) +#define DKP_IS_DAEMON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_TYPE_DAEMON)) +#define DKP_IS_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_TYPE_DAEMON)) +#define DKP_DAEMON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_DAEMON, DkpDaemonClass)) typedef struct DkpDaemonPrivate DkpDaemonPrivate; diff --git a/src/dkp-device.c b/src/dkp-device.c index b706e5b..a76829e 100644 --- a/src/dkp-device.c +++ b/src/dkp-device.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2008 David Zeuthen <david@fubar.dk> + * Copyright (C) 2008 Richard Hughes <richard@hughsie.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,30 +36,184 @@ #include "sysfs-utils.h" #include "dkp-debug.h" +#include "dkp-supply.h" #include "dkp-device.h" -#include "dkp-source.h" +#include "dkp-device.h" +#include "dkp-history-obj.h" +#include "dkp-marshal.h" +#include "dkp-device-glue.h" + +struct DkpDevicePrivate +{ + gchar *object_path; + DBusGConnection *system_bus_connection; + DBusGProxy *system_bus_proxy; + DkpDaemon *daemon; + DevkitDevice *d; + DkpObject *obj; + gboolean has_ever_refresh; +}; + +static void dkp_device_class_init (DkpDeviceClass *klass); +static void dkp_device_init (DkpDevice *device); +static gboolean dkp_device_register_device (DkpDevice *device); +static gboolean dkp_device_refresh_internal (DkpDevice *device); + +enum +{ + PROP_0, + PROP_NATIVE_PATH, + PROP_VENDOR, + PROP_MODEL, + PROP_SERIAL, + PROP_UPDATE_TIME, + PROP_TYPE, + PROP_LINE_POWER_ONLINE, + PROP_POWER_SUPPLY, + PROP_BATTERY_CAPACITY, + PROP_BATTERY_IS_PRESENT, + PROP_BATTERY_IS_RECHARGEABLE, + PROP_BATTERY_STATE, + PROP_BATTERY_ENERGY, + PROP_BATTERY_ENERGY_EMPTY, + PROP_BATTERY_ENERGY_FULL, + PROP_BATTERY_ENERGY_FULL_DESIGN, + PROP_BATTERY_ENERGY_RATE, + PROP_BATTERY_TIME_TO_EMPTY, + PROP_BATTERY_TIME_TO_FULL, + PROP_BATTERY_PERCENTAGE, + PROP_BATTERY_TECHNOLOGY, +}; + +enum +{ + CHANGED_SIGNAL, + LAST_SIGNAL, +}; -static void dkp_device_class_init (DkpDeviceClass *klass); -static void dkp_device_init (DkpDevice *seat); +static guint signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (DkpDevice, dkp_device, G_TYPE_OBJECT) +#define DKP_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_TYPE_DEVICE, DkpDevicePrivate)) +#define DKP_DBUS_STRUCT_UINT_DOUBLE_STRING (dbus_g_type_get_struct ("GValueArray", \ + G_TYPE_UINT, G_TYPE_DOUBLE, G_TYPE_STRING, G_TYPE_INVALID)) + +/** + * dkp_device_error_quark: + **/ +GQuark +dkp_device_error_quark (void) +{ + static GQuark ret = 0; + + if (ret == 0) { + ret = g_quark_from_static_string ("dkp_device_error"); + } + + return ret; +} -#define DKP_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_SOURCE_TYPE_DEVICE, DkpDevicePrivate)) +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } /** - * dkp_device_class_init: + * dkp_device_error_get_type: **/ -static void -dkp_device_class_init (DkpDeviceClass *klass) +GType +dkp_device_error_get_type (void) { + static GType etype = 0; + + if (etype == 0) + { + static const GEnumValue values[] = + { + ENUM_ENTRY (DKP_DEVICE_ERROR_GENERAL, "GeneralError"), + { 0, 0, 0 } + }; + g_assert (DKP_DEVICE_NUM_ERRORS == G_N_ELEMENTS (values) - 1); + etype = g_enum_register_static ("DkpDeviceError", values); + } + return etype; } /** - * dkp_device_init: + * dkp_device_get_property: **/ static void -dkp_device_init (DkpDevice *device) +dkp_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { + DkpDevice *device = DKP_DEVICE (object); + DkpObject *obj = device->priv->obj; + + switch (prop_id) { + case PROP_NATIVE_PATH: + g_value_set_string (value, obj->native_path); + break; + case PROP_VENDOR: + g_value_set_string (value, obj->vendor); + break; + case PROP_MODEL: + g_value_set_string (value, obj->model); + break; + case PROP_SERIAL: + g_value_set_string (value, obj->serial); + break; + case PROP_UPDATE_TIME: + g_value_set_uint64 (value, obj->update_time); + break; + case PROP_TYPE: + g_value_set_string (value, dkp_source_type_to_text (obj->type)); + break; + case PROP_POWER_SUPPLY: + g_value_set_boolean (value, obj->power_supply); + break; + case PROP_LINE_POWER_ONLINE: + g_value_set_boolean (value, obj->line_power_online); + break; + case PROP_BATTERY_IS_PRESENT: + g_value_set_boolean (value, obj->battery_is_present); + break; + case PROP_BATTERY_IS_RECHARGEABLE: + g_value_set_boolean (value, obj->battery_is_rechargeable); + break; + case PROP_BATTERY_STATE: + g_value_set_string (value, dkp_source_state_to_text (obj->battery_state)); + break; + case PROP_BATTERY_CAPACITY: + g_value_set_double (value, obj->battery_capacity); + break; + case PROP_BATTERY_ENERGY: + g_value_set_double (value, obj->battery_energy); + break; + case PROP_BATTERY_ENERGY_EMPTY: + g_value_set_double (value, obj->battery_energy_empty); + break; + case PROP_BATTERY_ENERGY_FULL: + g_value_set_double (value, obj->battery_energy_full); + break; + case PROP_BATTERY_ENERGY_FULL_DESIGN: + g_value_set_double (value, obj->battery_energy_full_design); + break; + case PROP_BATTERY_ENERGY_RATE: + g_value_set_double (value, obj->battery_energy_rate); + break; + case PROP_BATTERY_TIME_TO_EMPTY: + g_value_set_int64 (value, obj->battery_time_to_empty); + break; + case PROP_BATTERY_TIME_TO_FULL: + g_value_set_int64 (value, obj->battery_time_to_full); + break; + case PROP_BATTERY_PERCENTAGE: + g_value_set_double (value, obj->battery_percentage); + break; + case PROP_BATTERY_TECHNOLOGY: + g_value_set_string (value, dkp_source_technology_to_text (obj->battery_technology)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } /** @@ -67,36 +222,172 @@ dkp_device_init (DkpDevice *device) void dkp_device_removed (DkpDevice *device) { + //DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); + //klass->removed (device); + dkp_warning ("do something here?"); +} + +/** + * dkp_device_get_on_battery: + **/ +gboolean +dkp_device_get_on_battery (DkpDevice *device, gboolean *on_battery) +{ DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); - klass->removed (device); + return klass->get_on_battery (device, on_battery); } /** - * dkp_device_new: + * dkp_device_get_low_battery: **/ -DkpDevice * -dkp_device_new (DkpDaemon *daemon, DevkitDevice *d) +gboolean +dkp_device_get_low_battery (DkpDevice *device, gboolean *low_battery) { - const gchar *subsys; - DkpDevice *device; + DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); + return klass->get_low_battery (device, low_battery); +} + +/** + * dkp_device_coldplug: + **/ +gboolean +dkp_device_coldplug (DkpDevice *device, DkpDaemon *daemon, DevkitDevice *d) +{ + gboolean ret; + const gchar *native_path; + DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); + + /* save */ + device->priv->d = g_object_ref (d); + device->priv->daemon = g_object_ref (daemon); + + native_path = devkit_device_get_native_path (d); + device->priv->obj->native_path = g_strdup (native_path); + + /* coldplug source */ + dkp_debug ("coldplug %s", native_path); + ret = klass->coldplug (device); + /* only put on the bus if we succeeded */ + if (ret) + dkp_device_register_device (device); + + /* force a refresh */ + dkp_device_refresh_internal (device); + + return ret; +} + +/** + * dkp_device_get_statistics: + **/ +gboolean +dkp_device_get_statistics (DkpDevice *device, const gchar *type, guint timespan, DBusGMethodInvocation *context) +{ + DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); + GError *error; + GPtrArray *array; + GPtrArray *complex; + const DkpHistoryObj *obj; + GValue *value; + guint i; - device = NULL; + array = klass->get_stats (device, type, timespan); + /* maybe the device doesn't support histories */ + if (array == NULL) { + error = g_error_new (DKP_DAEMON_ERROR, DKP_DAEMON_ERROR_GENERAL, "device has no history"); + dbus_g_method_return_error (context, error); + goto out; + } - subsys = devkit_device_get_subsystem (d); - if (strcmp (subsys, "power_supply") == 0) { - device = DKP_DEVICE (dkp_source_new (daemon, d)); + /* copy data to dbus struct */ + complex = g_ptr_array_sized_new (array->len); + for (i=0; i<array->len; i++) { + obj = (const DkpHistoryObj *) g_ptr_array_index (array, i); + value = g_new0 (GValue, 1); + g_value_init (value, DKP_DBUS_STRUCT_UINT_DOUBLE_STRING); + g_value_take_boxed (value, dbus_g_type_specialized_construct (DKP_DBUS_STRUCT_UINT_DOUBLE_STRING)); + dbus_g_type_struct_set (value, 0, obj->time, 1, obj->value, 2, dkp_source_state_to_text (obj->state), -1); + g_ptr_array_add (complex, g_value_get_boxed (value)); + g_free (value); } - return device; + + g_ptr_array_free (array, TRUE); + dbus_g_method_return (context, complex); +out: + return TRUE; +} + +/** + * dkp_device_refresh_internal: + **/ +static gboolean +dkp_device_refresh_internal (DkpDevice *device) +{ + DkpObject *obj = dkp_device_get_obj (device); + DkpObject *obj_old; + gboolean ret; + gboolean success; + DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); + + /* make a copy so we can see if anything changed */ + obj_old = dkp_object_copy (obj); + + /* do the refresh */ + success = klass->refresh (device); + if (!success) + goto out; + + /* the first time, print all properties */ + if (!device->priv->has_ever_refresh) { + dkp_object_print (obj); + device->priv->has_ever_refresh = TRUE; + goto out; + } + + /* print difference */ + ret = !dkp_object_equal (obj, obj_old); + if (ret) + dkp_object_diff (obj_old, obj); +out: + dkp_object_free (obj_old); + return success; +} + +/** + * dkp_device_refresh: + **/ +gboolean +dkp_device_refresh (DkpDevice *device, DBusGMethodInvocation *context) +{ + gboolean ret; + ret = dkp_device_refresh_internal (device); + dbus_g_method_return (context); + return ret; } + /** * dkp_device_changed: **/ gboolean dkp_device_changed (DkpDevice *device, DevkitDevice *d, gboolean synthesized) { - DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); - return (klass->changed (device, d, synthesized)); + gboolean keep_device; + + g_object_unref (device->priv->d); + device->priv->d = g_object_ref (d); + + keep_device = dkp_device_refresh_internal (device); + + /* this 'change' event might prompt us to remove the supply */ + if (!keep_device) + goto out; + + /* no, it's good .. keep it */ + dkp_device_emit_changed (device); + +out: + return keep_device; } /** @@ -105,27 +396,244 @@ dkp_device_changed (DkpDevice *device, DevkitDevice *d, gboolean synthesized) const gchar * dkp_device_get_object_path (DkpDevice *device) { - DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); - return klass->get_object_path (device); + return device->priv->object_path; +} + +DkpObject * +dkp_device_get_obj (DkpDevice *device) +{ + return device->priv->obj; +} + +DevkitDevice * +dkp_device_get_d (DkpDevice *device) +{ + return device->priv->d; } /** - * dkp_device_get_on_battery: + * dkp_device_emit_changed: **/ -gboolean -dkp_device_get_on_battery (DkpDevice *device, gboolean *on_battery) +void +dkp_device_emit_changed (DkpDevice *device) { - DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); - return klass->get_on_battery (device, on_battery); + dkp_debug ("emitting changed on %s", device->priv->obj->native_path); + g_signal_emit_by_name (device->priv->daemon, "device-changed", + device->priv->object_path, NULL); + g_signal_emit (device, signals[CHANGED_SIGNAL], 0); } /** - * dkp_device_get_low_battery: + * dkp_device_compute_object_path_from_basename: **/ -gboolean -dkp_device_get_low_battery (DkpDevice *device, gboolean *low_battery) +static char * +dkp_device_compute_object_path_from_basename (const char *native_path_basename) { - DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device); - return klass->get_low_battery (device, low_battery); + gchar *basename; + gchar *object_path; + unsigned int n; + + /* TODO: need to be more thorough with making proper object + * names that won't make D-Bus crash. This is just to cope + * with dm-0... + */ + basename = g_path_get_basename (native_path_basename); + for (n = 0; basename[n] != '\0'; n++) + if (basename[n] == '-') + basename[n] = '_'; + object_path = g_build_filename ("/devices/", basename, NULL); + g_free (basename); + + return object_path; +} + +/** + * dkp_device_compute_object_path: + **/ +static gchar * +dkp_device_compute_object_path (const char *native_path) +{ + gchar *basename; + gchar *object_path; + + basename = g_path_get_basename (native_path); + object_path = dkp_device_compute_object_path_from_basename (basename); + g_free (basename); + return object_path; +} + +/** + * dkp_device_register_device: + **/ +static gboolean +dkp_device_register_device (DkpDevice *device) +{ + gboolean ret = TRUE; + + device->priv->object_path = dkp_device_compute_object_path (device->priv->obj->native_path); + dbus_g_connection_register_g_object (device->priv->system_bus_connection, + device->priv->object_path, G_OBJECT (device)); + device->priv->system_bus_proxy = dbus_g_proxy_new_for_name (device->priv->system_bus_connection, + DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); + if (device->priv->system_bus_proxy == NULL) { + dkp_warning ("proxy invalid"); + ret = FALSE; + } + return ret; +} + +/** + * dkp_device_init: + **/ +static void +dkp_device_init (DkpDevice *device) +{ + GError *error = NULL; + + device->priv = DKP_DEVICE_GET_PRIVATE (device); + device->priv->object_path = NULL; + device->priv->system_bus_connection = NULL; + device->priv->system_bus_proxy = NULL; + device->priv->daemon = NULL; + device->priv->d = NULL; + device->priv->has_ever_refresh = FALSE; + device->priv->obj = dkp_object_new (); + + device->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (device->priv->system_bus_connection == NULL) { + dkp_error ("error getting system bus: %s", error->message); + g_error_free (error); + } +} + +/** + * dkp_device_finalize: + **/ +static void +dkp_device_finalize (GObject *object) +{ + DkpDevice *device; + + g_return_if_fail (object != NULL); + g_return_if_fail (DKP_IS_DEVICE (object)); + + device = DKP_DEVICE (object); + g_return_if_fail (device->priv != NULL); + g_object_unref (device->priv->d); + g_object_unref (device->priv->daemon); + dkp_object_free (device->priv->obj); + + G_OBJECT_CLASS (dkp_device_parent_class)->finalize (object); +} + +/** + * dkp_device_class_init: + **/ +static void +dkp_device_class_init (DkpDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->get_property = dkp_device_get_property; + object_class->finalize = dkp_device_finalize; + + + g_type_class_add_private (klass, sizeof (DkpDevicePrivate)); + + signals[CHANGED_SIGNAL] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + dbus_g_object_type_install_info (DKP_TYPE_DEVICE, &dbus_glib_dkp_device_object_info); + + g_object_class_install_property ( + object_class, + PROP_NATIVE_PATH, + g_param_spec_string ("native-path", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_VENDOR, + g_param_spec_string ("vendor", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_MODEL, + g_param_spec_string ("model", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_SERIAL, + g_param_spec_string ("serial", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_UPDATE_TIME, + g_param_spec_uint64 ("update-time", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_TYPE, + g_param_spec_string ("type", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_IS_PRESENT, + g_param_spec_boolean ("power-supply", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_LINE_POWER_ONLINE, + g_param_spec_boolean ("line-power-online", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_ENERGY, + g_param_spec_double ("battery-energy", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_IS_PRESENT, + g_param_spec_boolean ("battery-is-present", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_IS_RECHARGEABLE, + g_param_spec_boolean ("battery-is-rechargeable", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_STATE, + g_param_spec_string ("battery-state", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_CAPACITY, + g_param_spec_double ("battery-capacity", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_ENERGY_EMPTY, + g_param_spec_double ("battery-energy-empty", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_ENERGY_FULL, + g_param_spec_double ("battery-energy-full", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_ENERGY_FULL_DESIGN, + g_param_spec_double ("battery-energy-full-design", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_ENERGY_RATE, + g_param_spec_double ("battery-energy-rate", NULL, NULL, -G_MAXDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_TIME_TO_EMPTY, + g_param_spec_int64 ("battery-time-to-empty", NULL, NULL, -1, G_MAXINT64, -1, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_TIME_TO_FULL, + g_param_spec_int64 ("battery-time-to-full", NULL, NULL, -1, G_MAXINT64, -1, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_PERCENTAGE, + g_param_spec_double ("battery-percentage", NULL, NULL, -1, 100, -1, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_BATTERY_TECHNOLOGY, + g_param_spec_string ("battery-technology", NULL, NULL, NULL, G_PARAM_READABLE)); + + dbus_g_error_domain_register (DKP_DEVICE_ERROR, NULL, DKP_DEVICE_TYPE_ERROR); } diff --git a/src/dkp-device.h b/src/dkp-device.h index fc5d0e2..9724948 100644 --- a/src/dkp-device.h +++ b/src/dkp-device.h @@ -25,21 +25,26 @@ #include <glib-object.h> #include <polkit-dbus/polkit-dbus.h> #include <devkit-gobject.h> +#include <dbus/dbus-glib.h> +#include "dkp-object.h" #include "dkp-daemon.h" G_BEGIN_DECLS -#define DKP_SOURCE_TYPE_DEVICE (dkp_device_get_type ()) -#define DKP_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_SOURCE_TYPE_DEVICE, DkpDevice)) -#define DKP_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_SOURCE_TYPE_DEVICE, DkpDeviceClass)) -#define DKP_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_SOURCE_TYPE_DEVICE)) -#define DKP_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_SOURCE_TYPE_DEVICE)) -#define DKP_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_SOURCE_TYPE_DEVICE, DkpDeviceClass)) +#define DKP_TYPE_DEVICE (dkp_device_get_type ()) +#define DKP_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_TYPE_DEVICE, DkpDevice)) +#define DKP_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_TYPE_DEVICE, DkpDeviceClass)) +#define DKP_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_TYPE_DEVICE)) +#define DKP_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_TYPE_DEVICE)) +#define DKP_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_DEVICE, DkpDeviceClass)) + +typedef struct DkpDevicePrivate DkpDevicePrivate; typedef struct { - GObject parent; + GObject parent; + DkpDevicePrivate *priv; } DkpDevice; typedef struct @@ -47,29 +52,53 @@ typedef struct GObjectClass parent_class; /* vtable */ - gboolean (*changed) (DkpDevice *device, - DevkitDevice *d, - gboolean synthesized); - void (*removed) (DkpDevice *device); - const gchar *(*get_object_path) (DkpDevice *device); + gboolean (*coldplug) (DkpDevice *device); + gboolean (*refresh) (DkpDevice *device); + const gchar *(*get_id) (DkpDevice *device); gboolean (*get_on_battery) (DkpDevice *device, gboolean *on_battery); gboolean (*get_low_battery) (DkpDevice *device, gboolean *low_battery); + GPtrArray *(*get_stats) (DkpDevice *device, + const gchar *type, + guint timespan); } DkpDeviceClass; +typedef enum +{ + DKP_DEVICE_ERROR_GENERAL, + DKP_DEVICE_NUM_ERRORS +} DkpDeviceError; + +#define DKP_DEVICE_ERROR dkp_device_error_quark () +#define DKP_DEVICE_TYPE_ERROR (dkp_device_error_get_type ()) + +GQuark dkp_device_error_quark (void); +GType dkp_device_error_get_type (void); GType dkp_device_get_type (void); -DkpDevice *dkp_device_new (DkpDaemon *daemon, +gboolean dkp_device_coldplug (DkpDevice *device, + DkpDaemon *daemon, DevkitDevice *d); gboolean dkp_device_changed (DkpDevice *device, DevkitDevice *d, gboolean synthesized); void dkp_device_removed (DkpDevice *device); +DkpObject *dkp_device_get_obj (DkpDevice *device); +DevkitDevice *dkp_device_get_d (DkpDevice *device); const gchar *dkp_device_get_object_path (DkpDevice *device); gboolean dkp_device_get_on_battery (DkpDevice *device, gboolean *on_battery); gboolean dkp_device_get_low_battery (DkpDevice *device, gboolean *low_battery); +void dkp_device_emit_changed (DkpDevice *device); + +/* exported methods */ +gboolean dkp_device_refresh (DkpDevice *device, + DBusGMethodInvocation *context); +gboolean dkp_device_get_statistics (DkpDevice *device, + const gchar *type, + guint timespan, + DBusGMethodInvocation *context); G_END_DECLS diff --git a/src/dkp-source.c b/src/dkp-source.c deleted file mode 100644 index c14ded6..0000000 --- a/src/dkp-source.c +++ /dev/null @@ -1,991 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 David Zeuthen <david@fubar.dk> - * Copyright (C) 2008 Richard Hughes <richard@hughsie.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <string.h> -#include <math.h> - -#include <glib.h> -#include <glib/gstdio.h> -#include <glib/gi18n-lib.h> -#include <glib-object.h> -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> -#include <devkit-gobject.h> -#include <polkit-dbus/polkit-dbus.h> - -#include "sysfs-utils.h" -#include "dkp-debug.h" -#include "dkp-enum.h" -#include "dkp-object.h" -#include "dkp-source.h" -#include "dkp-history.h" -#include "dkp-history-obj.h" -#include "dkp-marshal.h" -#include "dkp-source-glue.h" - -#define DK_POWER_MIN_CHARGED_PERCENTAGE 60 - -struct DkpSourcePrivate -{ - DBusGConnection *system_bus_connection; - DBusGProxy *system_bus_proxy; - DkpDaemon *daemon; - DevkitDevice *d; - DkpHistory *history; - gchar *object_path; - guint poll_timer_id; - DkpObject *obj; - gboolean has_coldplug_values; - gdouble battery_energy_old; - GTimeVal battery_energy_old_timespec; -}; - -static void dkp_source_class_init (DkpSourceClass *klass); -static void dkp_source_init (DkpSource *source); -static void dkp_source_finalize (GObject *object); -static void dkp_source_reset_values (DkpSource *source); -static gboolean dkp_source_update (DkpSource *source); - -enum -{ - PROP_0, - PROP_NATIVE_PATH, - PROP_VENDOR, - PROP_MODEL, - PROP_SERIAL, - PROP_UPDATE_TIME, - PROP_TYPE, - PROP_LINE_POWER_ONLINE, - PROP_POWER_SUPPLY, - PROP_BATTERY_CAPACITY, - PROP_BATTERY_IS_PRESENT, - PROP_BATTERY_IS_RECHARGEABLE, - PROP_BATTERY_STATE, - PROP_BATTERY_ENERGY, - PROP_BATTERY_ENERGY_EMPTY, - PROP_BATTERY_ENERGY_FULL, - PROP_BATTERY_ENERGY_FULL_DESIGN, - PROP_BATTERY_ENERGY_RATE, - PROP_BATTERY_TIME_TO_EMPTY, - PROP_BATTERY_TIME_TO_FULL, - PROP_BATTERY_PERCENTAGE, - PROP_BATTERY_TECHNOLOGY, -}; - -enum -{ - CHANGED_SIGNAL, - LAST_SIGNAL, -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (DkpSource, dkp_source, DKP_SOURCE_TYPE_DEVICE) -#define DKP_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_SOURCE_TYPE_SOURCE, DkpSourcePrivate)) - -static const char *dkp_source_get_object_path (DkpDevice *device); -static gboolean dkp_source_get_on_battery (DkpDevice *device, gboolean *on_battery); -static gboolean dkp_source_get_low_battery (DkpDevice *device, gboolean *low_battery); -static void dkp_source_removed (DkpDevice *device); -static gboolean dkp_source_changed (DkpDevice *device, DevkitDevice *d, gboolean synthesized); - -/** - * dkp_source_error_quark: - **/ -GQuark -dkp_source_error_quark (void) -{ - static GQuark ret = 0; - - if (ret == 0) { - ret = g_quark_from_static_string ("dkp_source_error"); - } - - return ret; -} - -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -/** - * dkp_source_error_get_type: - **/ -GType -dkp_source_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) - { - static const GEnumValue values[] = - { - ENUM_ENTRY (DKP_SOURCE_ERROR_GENERAL, "GeneralError"), - { 0, 0, 0 } - }; - g_assert (DKP_SOURCE_NUM_ERRORS == G_N_ELEMENTS (values) - 1); - etype = g_enum_register_static ("DkpSourceError", values); - } - return etype; -} - -/** - * dkp_source_get_property: - **/ -static void -dkp_source_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - DkpSource *source = DKP_SOURCE (object); - DkpObject *obj = source->priv->obj; - - switch (prop_id) { - case PROP_NATIVE_PATH: - g_value_set_string (value, obj->native_path); - break; - case PROP_VENDOR: - g_value_set_string (value, obj->vendor); - break; - case PROP_MODEL: - g_value_set_string (value, obj->model); - break; - case PROP_SERIAL: - g_value_set_string (value, obj->serial); - break; - case PROP_UPDATE_TIME: - g_value_set_uint64 (value, obj->update_time); - break; - case PROP_TYPE: - g_value_set_string (value, dkp_source_type_to_text (obj->type)); - break; - case PROP_POWER_SUPPLY: - g_value_set_boolean (value, obj->power_supply); - break; - case PROP_LINE_POWER_ONLINE: - g_value_set_boolean (value, obj->line_power_online); - break; - case PROP_BATTERY_IS_PRESENT: - g_value_set_boolean (value, obj->battery_is_present); - break; - case PROP_BATTERY_IS_RECHARGEABLE: - g_value_set_boolean (value, obj->battery_is_rechargeable); - break; - case PROP_BATTERY_STATE: - g_value_set_string (value, dkp_source_state_to_text (obj->battery_state)); - break; - case PROP_BATTERY_CAPACITY: - g_value_set_double (value, obj->battery_capacity); - break; - case PROP_BATTERY_ENERGY: - g_value_set_double (value, obj->battery_energy); - break; - case PROP_BATTERY_ENERGY_EMPTY: - g_value_set_double (value, obj->battery_energy_empty); - break; - case PROP_BATTERY_ENERGY_FULL: - g_value_set_double (value, obj->battery_energy_full); - break; - case PROP_BATTERY_ENERGY_FULL_DESIGN: - g_value_set_double (value, obj->battery_energy_full_design); - break; - case PROP_BATTERY_ENERGY_RATE: - g_value_set_double (value, obj->battery_energy_rate); - break; - case PROP_BATTERY_TIME_TO_EMPTY: - g_value_set_int64 (value, obj->battery_time_to_empty); - break; - case PROP_BATTERY_TIME_TO_FULL: - g_value_set_int64 (value, obj->battery_time_to_full); - break; - case PROP_BATTERY_PERCENTAGE: - g_value_set_double (value, obj->battery_percentage); - break; - case PROP_BATTERY_TECHNOLOGY: - g_value_set_string (value, dkp_source_technology_to_text (obj->battery_technology)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/** - * dkp_source_class_init: - **/ -static void -dkp_source_class_init (DkpSourceClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - DkpDeviceClass *device_class = DKP_DEVICE_CLASS (klass); - - object_class->finalize = dkp_source_finalize; - object_class->get_property = dkp_source_get_property; - device_class->changed = dkp_source_changed; - device_class->removed = dkp_source_removed; - device_class->get_object_path = dkp_source_get_object_path; - device_class->get_on_battery = dkp_source_get_on_battery; - device_class->get_low_battery = dkp_source_get_low_battery; - - g_type_class_add_private (klass, sizeof (DkpSourcePrivate)); - - signals[CHANGED_SIGNAL] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - dbus_g_object_type_install_info (DKP_SOURCE_TYPE_SOURCE, &dbus_glib_dkp_source_object_info); - - g_object_class_install_property ( - object_class, - PROP_NATIVE_PATH, - g_param_spec_string ("native-path", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_VENDOR, - g_param_spec_string ("vendor", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_MODEL, - g_param_spec_string ("model", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_SERIAL, - g_param_spec_string ("serial", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_UPDATE_TIME, - g_param_spec_uint64 ("update-time", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_TYPE, - g_param_spec_string ("type", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_IS_PRESENT, - g_param_spec_boolean ("power-supply", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINE_POWER_ONLINE, - g_param_spec_boolean ("line-power-online", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_ENERGY, - g_param_spec_double ("battery-energy", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_IS_PRESENT, - g_param_spec_boolean ("battery-is-present", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_IS_RECHARGEABLE, - g_param_spec_boolean ("battery-is-rechargeable", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_STATE, - g_param_spec_string ("battery-state", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_CAPACITY, - g_param_spec_double ("battery-capacity", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_ENERGY_EMPTY, - g_param_spec_double ("battery-energy-empty", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_ENERGY_FULL, - g_param_spec_double ("battery-energy-full", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_ENERGY_FULL_DESIGN, - g_param_spec_double ("battery-energy-full-design", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_ENERGY_RATE, - g_param_spec_double ("battery-energy-rate", NULL, NULL, -G_MAXDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_TIME_TO_EMPTY, - g_param_spec_int64 ("battery-time-to-empty", NULL, NULL, -1, G_MAXINT64, -1, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_TIME_TO_FULL, - g_param_spec_int64 ("battery-time-to-full", NULL, NULL, -1, G_MAXINT64, -1, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_PERCENTAGE, - g_param_spec_double ("battery-percentage", NULL, NULL, -1, 100, -1, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_BATTERY_TECHNOLOGY, - g_param_spec_string ("battery-technology", NULL, NULL, NULL, G_PARAM_READABLE)); - - dbus_g_error_domain_register (DKP_SOURCE_ERROR, NULL, DKP_SOURCE_TYPE_ERROR); -} - -/** - * dkp_source_init: - **/ -static void -dkp_source_init (DkpSource *source) -{ - source->priv = DKP_SOURCE_GET_PRIVATE (source); - dkp_source_reset_values (source); -} - -/** - * dkp_source_finalize: - **/ -static void -dkp_source_finalize (GObject *object) -{ - DkpSource *source; - - g_return_if_fail (object != NULL); - g_return_if_fail (DKP_IS_SOURCE (object)); - - source = DKP_SOURCE (object); - g_return_if_fail (source->priv != NULL); - - g_object_unref (source->priv->d); - g_object_unref (source->priv->daemon); - g_object_unref (source->priv->history); - dkp_object_free (source->priv->obj); - - if (source->priv->poll_timer_id > 0) - g_source_remove (source->priv->poll_timer_id); - - G_OBJECT_CLASS (dkp_source_parent_class)->finalize (object); -} - -/** - * dkp_source_compute_object_path_from_basename: - **/ -static char * -dkp_source_compute_object_path_from_basename (const char *native_path_basename) -{ - gchar *basename; - gchar *object_path; - unsigned int n; - - /* TODO: need to be more thorough with making proper object - * names that won't make D-Bus crash. This is just to cope - * with dm-0... - */ - basename = g_path_get_basename (native_path_basename); - for (n = 0; basename[n] != '\0'; n++) - if (basename[n] == '-') - basename[n] = '_'; - object_path = g_build_filename ("/sources/", basename, NULL); - g_free (basename); - - return object_path; -} - -/** - * dkp_source_compute_object_path: - **/ -static gchar * -dkp_source_compute_object_path (const char *native_path) -{ - gchar *basename; - gchar *object_path; - - basename = g_path_get_basename (native_path); - object_path = dkp_source_compute_object_path_from_basename (basename); - g_free (basename); - return object_path; -} - -/** - * dkp_source_register_source: - **/ -static gboolean -dkp_source_register_source (DkpSource *source) -{ - DBusConnection *connection; - GError *error = NULL; - - source->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (source->priv->system_bus_connection == NULL) { - if (error != NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - } - goto error; - } - connection = dbus_g_connection_get_connection (source->priv->system_bus_connection); - - source->priv->object_path = dkp_source_compute_object_path (source->priv->obj->native_path); - - dbus_g_connection_register_g_object (source->priv->system_bus_connection, - source->priv->object_path, G_OBJECT (source)); - - source->priv->system_bus_proxy = dbus_g_proxy_new_for_name (source->priv->system_bus_connection, - DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); - - return TRUE; - -error: - return FALSE; -} - -/** - * dkp_source_new: - **/ -DkpSource * -dkp_source_new (DkpDaemon *daemon, DevkitDevice *d) -{ - DkpSource *source; - const gchar *native_path; - gchar *id; - - source = NULL; - native_path = devkit_device_get_native_path (d); - - source = DKP_SOURCE (g_object_new (DKP_SOURCE_TYPE_SOURCE, NULL)); - source->priv->d = g_object_ref (d); - source->priv->daemon = g_object_ref (daemon); - source->priv->obj = dkp_object_new (); - source->priv->obj->native_path = g_strdup (native_path); - source->priv->history = dkp_history_new (); - - /* detect what kind of device we are */ - if (sysfs_file_exists (native_path, "online")) { - source->priv->obj->type = DKP_SOURCE_TYPE_LINE_POWER; - } else { - /* this is correct, UPS and CSR are not in the kernel */ - source->priv->obj->type = DKP_SOURCE_TYPE_BATTERY; - } - - /* coldplug */ - if (!dkp_source_update (source)) { - dkp_warning ("coldplug of %s failed", source->priv->obj->native_path); - g_object_unref (source); - source = NULL; - goto out; - } - - /* register on the bus */ - if (!dkp_source_register_source (DKP_SOURCE (source))) { - dkp_warning ("failed to register on the bus"); - g_object_unref (source); - source = NULL; - goto out; - } - - /* get the id so we can load the old history */ - id = dkp_object_get_id (source->priv->obj); - if (id != NULL) - dkp_history_set_id (source->priv->history, id); - g_free (id); - -out: - return source; -} - -/** - * dkp_source_emit_changed: - **/ -static void -dkp_source_emit_changed (DkpSource *source) -{ - dkp_debug ("emitting changed on %s", source->priv->obj->native_path); - g_signal_emit_by_name (source->priv->daemon, "device-changed", - source->priv->object_path, NULL); - g_signal_emit (source, signals[CHANGED_SIGNAL], 0); -} - -/** - * dkp_source_changed: - **/ -static gboolean -dkp_source_changed (DkpDevice *device, DevkitDevice *d, gboolean synthesized) -{ - DkpSource *source = DKP_SOURCE (device); - gboolean keep_source; - - g_object_unref (source->priv->d); - source->priv->d = g_object_ref (d); - - keep_source = dkp_source_update (source); - - /* this 'change' event might prompt us to remove the source */ - if (!keep_source) - goto out; - - /* no, it's good .. keep it */ - dkp_source_emit_changed (source); - -out: - return keep_source; -} - -/** - * dkp_source_removed: - **/ -void -dkp_source_removed (DkpDevice *device) -{ -} - -/** - * dkp_source_get_object_path: - **/ -static const char * -dkp_source_get_object_path (DkpDevice *device) -{ - DkpSource *source = DKP_SOURCE (device); - return source->priv->object_path; -} - -/** - * dkp_source_update_line_power: - **/ -static gboolean -dkp_source_update_line_power (DkpSource *source) -{ - DkpObject *obj = source->priv->obj; - DkpObject *obj_old; - gboolean ret; - - /* make a copy so we can see if anything changed */ - obj_old = dkp_object_copy (obj); - - /* force true */ - obj->power_supply = TRUE; - - /* get new AC value */ - obj->line_power_online = sysfs_get_int (obj->native_path, "online"); - - /* initial value */ - if (!source->priv->has_coldplug_values) { - dkp_object_print (obj); - source->priv->has_coldplug_values = TRUE; - goto out; - } - - /* print difference */ - ret = !dkp_object_equal (obj, obj_old); - if (ret) - dkp_object_diff (obj_old, obj); -out: - dkp_object_free (obj_old); - return TRUE; -} - -/** - * dkp_source_reset_values: - **/ -static void -dkp_source_reset_values (DkpSource *source) -{ - source->priv->has_coldplug_values = FALSE; - source->priv->battery_energy_old = -1; - source->priv->battery_energy_old_timespec.tv_sec = 0; - dkp_object_clear (source->priv->obj); -} - -/** - * dkp_source_get_on_battery: - **/ -static gboolean -dkp_source_get_on_battery (DkpDevice *device, gboolean *on_battery) -{ - DkpSource *source = DKP_SOURCE (device); - - g_return_val_if_fail (DKP_IS_SOURCE (source), FALSE); - g_return_val_if_fail (on_battery != NULL, FALSE); - - if (source->priv->obj->type != DKP_SOURCE_TYPE_BATTERY) - return FALSE; - if (!source->priv->obj->battery_is_present) - return FALSE; - - *on_battery = (source->priv->obj->battery_state == DKP_SOURCE_STATE_DISCHARGING); - return TRUE; -} - -/** - * dkp_source_get_low_battery: - **/ -static gboolean -dkp_source_get_low_battery (DkpDevice *device, gboolean *low_battery) -{ - gboolean ret; - gboolean on_battery; - DkpSource *source = DKP_SOURCE (device); - - g_return_val_if_fail (DKP_IS_SOURCE (source), FALSE); - g_return_val_if_fail (low_battery != NULL, FALSE); - - /* reuse the common checks */ - ret = dkp_source_get_on_battery (device, &on_battery); - if (!ret) - return FALSE; - - /* shortcut */ - if (!on_battery) { - *low_battery = FALSE; - return TRUE; - } - - *low_battery = (source->priv->obj->battery_percentage < 10); - return TRUE; -} - -/** - * dkp_source_calculate_battery_rate: - **/ -static void -dkp_source_calculate_battery_rate (DkpSource *source) -{ - guint time; - gdouble energy; - GTimeVal now; - DkpObject *obj = source->priv->obj; - - if (obj->battery_energy < 0) - return; - - if (source->priv->battery_energy_old < 0) - return; - - if (source->priv->battery_energy_old == obj->battery_energy) - return; - - /* get the time difference */ - g_get_current_time (&now); - time = now.tv_sec - source->priv->battery_energy_old_timespec.tv_sec; - - if (time == 0) - return; - - /* get the difference in charge */ - energy = source->priv->battery_energy_old - obj->battery_energy; - if (energy < 0.1) - return; - - /* probably okay */ - obj->battery_energy_rate = energy * 3600 / time; -} - -/** - * dkp_source_update_battery: - * - * Return value: TRUE if we changed - **/ -static gboolean -dkp_source_update_battery (DkpSource *source) -{ - gchar *status = NULL; - gboolean ret; - gboolean just_added = FALSE; - DkpSourceState battery_state; - DkpObject *obj = source->priv->obj; - DkpObject *obj_old; - - /* make a copy so we can see if anything changed */ - obj_old = dkp_object_copy (obj); - - /* have we just been removed? */ - obj->battery_is_present = sysfs_get_bool (obj->native_path, "present"); - if (!obj->battery_is_present) { - dkp_source_reset_values (source); - obj->type = DKP_SOURCE_TYPE_BATTERY; - goto out; - } - - /* initial values */ - if (!source->priv->has_coldplug_values) { - gchar *technology_native; - - /* when we add via sysfs power_supply class then we know this is true */ - obj->power_supply = TRUE; - - /* the ACPI spec is bad at defining battery type constants */ - technology_native = g_strstrip (sysfs_get_string (obj->native_path, "technology")); - obj->battery_technology = dkp_acpi_to_source_technology (technology_native); - g_free (technology_native); - - obj->vendor = g_strstrip (sysfs_get_string (obj->native_path, "manufacturer")); - obj->model = g_strstrip (sysfs_get_string (obj->native_path, "model_name")); - obj->serial = g_strstrip (sysfs_get_string (obj->native_path, "serial_number")); - - /* assume true for laptops */ - obj->battery_is_rechargeable = TRUE; - - /* these don't change at runtime */ - obj->battery_energy_full = - sysfs_get_double (obj->native_path, "energy_full") / 1000000.0; - obj->battery_energy_full_design = - sysfs_get_double (obj->native_path, "energy_full_design") / 1000000.0; - - /* the last full cannot be bigger than the design */ - if (obj->battery_energy_full > obj->battery_energy_full_design) - obj->battery_energy_full = obj->battery_energy_full_design; - - /* calculate how broken our battery is */ - obj->battery_capacity = obj->battery_energy_full_design / obj->battery_energy_full * 100.0f; - if (obj->battery_capacity < 0) - obj->battery_capacity = 0; - if (obj->battery_capacity > 100.0) - obj->battery_capacity = 100.0; - - /* we only coldplug once, as these values will never change */ - source->priv->has_coldplug_values = TRUE; - just_added = TRUE; - } - - status = g_strstrip (sysfs_get_string (obj->native_path, "status")); - if (strcasecmp (status, "charging") == 0) - battery_state = DKP_SOURCE_STATE_CHARGING; - else if (strcasecmp (status, "discharging") == 0) - battery_state = DKP_SOURCE_STATE_DISCHARGING; - else if (strcasecmp (status, "full") == 0) - battery_state = DKP_SOURCE_STATE_FULLY_CHARGED; - else if (strcasecmp (status, "empty") == 0) - battery_state = DKP_SOURCE_STATE_EMPTY; - else { - dkp_warning ("unknown status string: %s", status); - battery_state = DKP_SOURCE_STATE_UNKNOWN; - } - - /* get the currect charge */ - obj->battery_energy = - sysfs_get_double (obj->native_path, "energy_avg") / 1000000.0; - if (obj->battery_energy == 0) - obj->battery_energy = - sysfs_get_double (obj->native_path, "energy_now") / 1000000.0; - - /* some batteries don't update last_full attribute */ - if (obj->battery_energy > obj->battery_energy_full) - obj->battery_energy_full = obj->battery_energy; - - obj->battery_energy_rate = - fabs (sysfs_get_double (obj->native_path, "current_now") / 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 (obj->battery_energy_rate == 0xffff) - obj->battery_energy_rate = -1; - - /* sanity check to less than 100W */ - if (obj->battery_energy_rate > 100*1000) - obj->battery_energy_rate = -1; - - /* the hardware reporting failed -- try to calculate this */ - if (obj->battery_energy_rate < 0) { - dkp_source_calculate_battery_rate (source); - } - - /* charging has a negative rate */ - if (obj->battery_energy_rate > 0 && battery_state == DKP_SOURCE_STATE_CHARGING) - obj->battery_energy_rate *= -1.0; - - /* get a precise percentage */ - obj->battery_percentage = 100.0 * obj->battery_energy / obj->battery_energy_full; - if (obj->battery_percentage < 0) - obj->battery_percentage = 0; - if (obj->battery_percentage > 100.0) - obj->battery_percentage = 100.0; - - /* calculate a quick and dirty time remaining value */ - obj->battery_time_to_empty = -1; - obj->battery_time_to_full = -1; - if (obj->battery_energy_rate > 0) { - if (battery_state == DKP_SOURCE_STATE_DISCHARGING) { - obj->battery_time_to_empty = 3600 * (obj->battery_energy / obj->battery_energy_rate); - } else if (battery_state == DKP_SOURCE_STATE_CHARGING) { - obj->battery_time_to_full = 3600 * ((obj->battery_energy_full - obj->battery_energy) / obj->battery_energy_rate); - } - } - /* check the remaining time is under a set limit, to deal with broken - primary batteries rate */ - if (obj->battery_time_to_empty > (100 * 60 * 60)) - obj->battery_time_to_empty = -1; - if (obj->battery_time_to_full > (100 * 60 * 60)) - obj->battery_time_to_full = -1; - - /* set the old status */ - source->priv->battery_energy_old = obj->battery_energy; - g_get_current_time (&source->priv->battery_energy_old_timespec); - - /* we changed state */ - if (obj->battery_state != battery_state) { - source->priv->battery_energy_old = -1; - obj->battery_state = battery_state; - } - -out: - /* did anything change? */ - ret = !dkp_object_equal (obj, obj_old); - if (!just_added && ret) - dkp_object_diff (obj_old, obj); - dkp_object_free (obj_old); - - /* just for debugging */ - if (just_added) - dkp_object_print (obj); - - /* save new history */ - if (ret) { - dkp_history_set_state (source->priv->history, obj->battery_state); - dkp_history_set_charge_data (source->priv->history, obj->battery_percentage); - dkp_history_set_rate_data (source->priv->history, obj->battery_energy_rate); - } - - g_free (status); - return ret; -} - -/** - * dkp_source_poll_battery: - **/ -static gboolean -dkp_source_poll_battery (DkpSource *source) -{ - gboolean ret; - DkpObject *obj = source->priv->obj; - - dkp_debug ("No updates on source %s for 30 seconds; forcing update", obj->native_path); - source->priv->poll_timer_id = 0; - ret = dkp_source_update (source); - if (ret) { - dkp_source_emit_changed (source); - } - return FALSE; -} - -/** - * dkp_source_update: - * - * Return value: TRUE if we changed - **/ -static gboolean -dkp_source_update (DkpSource *source) -{ - gboolean ret; - GTimeVal time; - DkpObject *obj = source->priv->obj; - - if (source->priv->poll_timer_id > 0) { - g_source_remove (source->priv->poll_timer_id); - source->priv->poll_timer_id = 0; - } - - g_get_current_time (&time); - obj->update_time = time.tv_sec; - - switch (source->priv->obj->type) { - case DKP_SOURCE_TYPE_LINE_POWER: - ret = dkp_source_update_line_power (source); - break; - case DKP_SOURCE_TYPE_BATTERY: - ret = dkp_source_update_battery (source); - /* Seems that we don't get change uevents from the - * kernel on some BIOS types; set up a timer to poll - * if we are charging or discharging */ - if (obj->battery_state == DKP_SOURCE_STATE_CHARGING || - obj->battery_state == DKP_SOURCE_STATE_DISCHARGING) - source->priv->poll_timer_id = g_timeout_add_seconds (30, (GSourceFunc) dkp_source_poll_battery, source); - break; - default: - g_assert_not_reached (); - break; - } - - return ret; -} - -#define DKP_DBUS_STRUCT_UINT_DOUBLE_STRING (dbus_g_type_get_struct ("GValueArray", \ - G_TYPE_UINT, G_TYPE_DOUBLE, G_TYPE_STRING, G_TYPE_INVALID)) - -/** - * dkp_source_get_statistics: - **/ -gboolean -dkp_source_get_statistics (DkpSource *source, const gchar *type, guint timespan, DBusGMethodInvocation *context) -{ - GError *error; - GPtrArray *array; - GPtrArray *complex; - const DkpHistoryObj *obj; - GValue *value; - guint i; - - g_return_val_if_fail (DKP_IS_SOURCE (source), FALSE); - g_return_val_if_fail (type != NULL, FALSE); - - /* get the correct data */ - if (strcmp (type, "rate") == 0) - array = dkp_history_get_rate_data (source->priv->history, timespan); - else if (strcmp (type, "charge") == 0) - array = dkp_history_get_charge_data (source->priv->history, timespan); - else { - error = g_error_new (DKP_DAEMON_ERROR, DKP_DAEMON_ERROR_GENERAL, "type '%s' not recognised", type); - dbus_g_method_return_error (context, error); - goto out; - } - - /* maybe the device doesn't support histories */ - if (array == NULL) { - error = g_error_new (DKP_DAEMON_ERROR, DKP_DAEMON_ERROR_GENERAL, "device has no history"); - dbus_g_method_return_error (context, error); - goto out; - } - - /* copy data to dbus struct */ - complex = g_ptr_array_sized_new (array->len); - for (i=0; i<array->len; i++) { - obj = (const DkpHistoryObj *) g_ptr_array_index (array, i); - value = g_new0 (GValue, 1); - g_value_init (value, DKP_DBUS_STRUCT_UINT_DOUBLE_STRING); - g_value_take_boxed (value, dbus_g_type_specialized_construct (DKP_DBUS_STRUCT_UINT_DOUBLE_STRING)); - dbus_g_type_struct_set (value, 0, obj->time, 1, obj->value, 2, dkp_source_state_to_text (obj->state), -1); - g_ptr_array_add (complex, g_value_get_boxed (value)); - g_free (value); - } - - g_ptr_array_free (array, TRUE); - dbus_g_method_return (context, complex); -out: - return TRUE; -} - -/** - * dkp_source_refresh: - **/ -gboolean -dkp_source_refresh (DkpSource *source, DBusGMethodInvocation *context) -{ - g_return_val_if_fail (DKP_IS_SOURCE (source), FALSE); - - dkp_source_update (source); - dbus_g_method_return (context); - return TRUE; -} diff --git a/src/dkp-source.h b/src/dkp-source.h deleted file mode 100644 index e32589f..0000000 --- a/src/dkp-source.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 David Zeuthen <david@fubar.dk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __DKP_SOURCE_H__ -#define __DKP_SOURCE_H__ - -#include <glib-object.h> -#include <polkit-dbus/polkit-dbus.h> -#include <devkit-gobject.h> - -#include "dkp-daemon.h" -#include "dkp-device.h" - -G_BEGIN_DECLS - -#define DKP_SOURCE_TYPE_SOURCE (dkp_source_get_type ()) -#define DKP_SOURCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_SOURCE_TYPE_SOURCE, DkpSource)) -#define DKP_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_SOURCE_TYPE_SOURCE, DkpSourceClass)) -#define DKP_IS_SOURCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_SOURCE_TYPE_SOURCE)) -#define DKP_IS_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_SOURCE_TYPE_SOURCE)) -#define DKP_SOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_SOURCE_TYPE_SOURCE, DkpSourceClass)) - -typedef struct DkpSourcePrivate DkpSourcePrivate; - -typedef struct -{ - DkpDevice parent; - DkpSourcePrivate *priv; -} DkpSource; - -typedef struct -{ - DkpDeviceClass parent_class; -} DkpSourceClass; - -typedef enum -{ - DKP_SOURCE_ERROR_GENERAL, - DKP_SOURCE_NUM_ERRORS -} DkpSourceError; - -#define DKP_SOURCE_ERROR dkp_source_error_quark () - -GType dkp_source_error_get_type (void); -#define DKP_SOURCE_TYPE_ERROR (dkp_source_error_get_type ()) - -GQuark dkp_source_error_quark (void); -GType dkp_source_get_type (void); -DkpSource *dkp_source_new (DkpDaemon *daemon, - DevkitDevice *d); - -/* exported methods */ -gboolean dkp_source_refresh (DkpSource *source, - DBusGMethodInvocation *context); -gboolean dkp_source_get_statistics (DkpSource *source, - const gchar *type, - guint timespan, - DBusGMethodInvocation *context); - -G_END_DECLS - -#endif /* __DKP_SOURCE_H__ */ diff --git a/src/dkp-supply.c b/src/dkp-supply.c new file mode 100644 index 0000000..ff2fae6 --- /dev/null +++ b/src/dkp-supply.c @@ -0,0 +1,520 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 David Zeuthen <david@fubar.dk> + * Copyright (C) 2008 Richard Hughes <richard@hughsie.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <string.h> +#include <math.h> + +#include <glib.h> +#include <glib/gstdio.h> +#include <glib/gi18n-lib.h> +#include <glib-object.h> +#include <devkit-gobject.h> + +#include "sysfs-utils.h" +#include "dkp-debug.h" +#include "dkp-enum.h" +#include "dkp-object.h" +#include "dkp-supply.h" +#include "dkp-history.h" + +#define DK_POWER_MIN_CHARGED_PERCENTAGE 60 + +struct DkpSupplyPrivate +{ + DkpHistory *history; + guint poll_timer_id; + gboolean has_coldplug_values; + gdouble battery_energy_old; + GTimeVal battery_energy_old_timespec; +}; + +static void dkp_supply_class_init (DkpSupplyClass *klass); + +G_DEFINE_TYPE (DkpSupply, dkp_supply, DKP_TYPE_DEVICE) +#define DKP_SUPPLY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_TYPE_SUPPLY, DkpSupplyPrivate)) + +static gboolean dkp_supply_refresh (DkpDevice *device); + +/** + * dkp_supply_refresh_line_power: + **/ +static gboolean +dkp_supply_refresh_line_power (DkpSupply *supply) +{ + DkpDevice *device = DKP_DEVICE (supply); + DkpObject *obj = dkp_device_get_obj (device); + + /* force true */ + obj->power_supply = TRUE; + + /* get new AC value */ + obj->line_power_online = sysfs_get_int (obj->native_path, "online"); + + return TRUE; +} + +/** + * dkp_supply_reset_values: + **/ +static void +dkp_supply_reset_values (DkpSupply *supply) +{ + gchar *native_path; + DkpSourceType type; + DkpDevice *device = DKP_DEVICE (supply); + DkpObject *obj = dkp_device_get_obj (device); + + /* some stuff we copy */ + type = obj->type; + native_path = g_strdup (obj->native_path); + + supply->priv->has_coldplug_values = FALSE; + supply->priv->battery_energy_old = -1; + supply->priv->battery_energy_old_timespec.tv_sec = 0; + dkp_object_clear (obj); + + /* restore the saved stuff */ + obj->type = type; + obj->native_path = native_path; +} + +/** + * dkp_supply_get_on_battery: + **/ +static gboolean +dkp_supply_get_on_battery (DkpDevice *device, gboolean *on_battery) +{ + DkpSupply *supply = DKP_SUPPLY (device); + DkpObject *obj = dkp_device_get_obj (device); + + g_return_val_if_fail (DKP_IS_SUPPLY (supply), FALSE); + g_return_val_if_fail (on_battery != NULL, FALSE); + + if (obj->type != DKP_SOURCE_TYPE_BATTERY) + return FALSE; + if (!obj->battery_is_present) + return FALSE; + + *on_battery = (obj->battery_state == DKP_SOURCE_STATE_DISCHARGING); + return TRUE; +} + +/** + * dkp_supply_get_low_battery: + **/ +static gboolean +dkp_supply_get_low_battery (DkpDevice *device, gboolean *low_battery) +{ + gboolean ret; + gboolean on_battery; + DkpSupply *supply = DKP_SUPPLY (device); + DkpObject *obj = dkp_device_get_obj (device); + + g_return_val_if_fail (DKP_IS_SUPPLY (supply), FALSE); + g_return_val_if_fail (low_battery != NULL, FALSE); + + /* reuse the common checks */ + ret = dkp_supply_get_on_battery (device, &on_battery); + if (!ret) + return FALSE; + + /* shortcut */ + if (!on_battery) { + *low_battery = FALSE; + return TRUE; + } + + *low_battery = (obj->battery_percentage < 10); + return TRUE; +} + +/** + * dkp_supply_calculate_battery_rate: + **/ +static void +dkp_supply_calculate_battery_rate (DkpSupply *supply) +{ + guint time; + gdouble energy; + GTimeVal now; + DkpDevice *device = DKP_DEVICE (supply); + DkpObject *obj = dkp_device_get_obj (device); + + if (obj->battery_energy < 0) + return; + + if (supply->priv->battery_energy_old < 0) + return; + + if (supply->priv->battery_energy_old == obj->battery_energy) + return; + + /* get the time difference */ + g_get_current_time (&now); + time = now.tv_sec - supply->priv->battery_energy_old_timespec.tv_sec; + + if (time == 0) + return; + + /* get the difference in charge */ + energy = supply->priv->battery_energy_old - obj->battery_energy; + if (energy < 0.1) + return; + + /* probably okay */ + obj->battery_energy_rate = energy * 3600 / time; +} + +/** + * dkp_supply_refresh_battery: + * + * Return value: TRUE if we changed + **/ +static gboolean +dkp_supply_refresh_battery (DkpSupply *supply) +{ + gchar *status = NULL; + gboolean ret = TRUE; + DkpSourceState battery_state; + DkpDevice *device = DKP_DEVICE (supply); + DkpObject *obj = dkp_device_get_obj (device); + + /* have we just been removed? */ + obj->battery_is_present = sysfs_get_bool (obj->native_path, "present"); + if (!obj->battery_is_present) { + dkp_supply_reset_values (supply); + obj->type = DKP_SOURCE_TYPE_BATTERY; + goto out; + } + + /* initial values */ + if (!supply->priv->has_coldplug_values) { + gchar *technology_native; + + /* when we add via sysfs power_supply class then we know this is true */ + obj->power_supply = TRUE; + + /* the ACPI spec is bad at defining battery type constants */ + technology_native = g_strstrip (sysfs_get_string (obj->native_path, "technology")); + obj->battery_technology = dkp_acpi_to_source_technology (technology_native); + g_free (technology_native); + + obj->vendor = g_strstrip (sysfs_get_string (obj->native_path, "manufacturer")); + obj->model = g_strstrip (sysfs_get_string (obj->native_path, "model_name")); + obj->serial = g_strstrip (sysfs_get_string (obj->native_path, "serial_number")); + + /* assume true for laptops */ + obj->battery_is_rechargeable = TRUE; + + /* these don't change at runtime */ + obj->battery_energy_full = + sysfs_get_double (obj->native_path, "energy_full") / 1000000.0; + obj->battery_energy_full_design = + sysfs_get_double (obj->native_path, "energy_full_design") / 1000000.0; + + /* the last full cannot be bigger than the design */ + if (obj->battery_energy_full > obj->battery_energy_full_design) + obj->battery_energy_full = obj->battery_energy_full_design; + + /* calculate how broken our battery is */ + obj->battery_capacity = obj->battery_energy_full_design / obj->battery_energy_full * 100.0f; + if (obj->battery_capacity < 0) + obj->battery_capacity = 0; + if (obj->battery_capacity > 100.0) + obj->battery_capacity = 100.0; + + /* we only coldplug once, as these values will never change */ + supply->priv->has_coldplug_values = TRUE; + } + + status = g_strstrip (sysfs_get_string (obj->native_path, "status")); + if (strcasecmp (status, "charging") == 0) + battery_state = DKP_SOURCE_STATE_CHARGING; + else if (strcasecmp (status, "discharging") == 0) + battery_state = DKP_SOURCE_STATE_DISCHARGING; + else if (strcasecmp (status, "full") == 0) + battery_state = DKP_SOURCE_STATE_FULLY_CHARGED; + else if (strcasecmp (status, "empty") == 0) + battery_state = DKP_SOURCE_STATE_EMPTY; + else { + dkp_warning ("unknown status string: %s", status); + battery_state = DKP_SOURCE_STATE_UNKNOWN; + } + + /* get the currect charge */ + obj->battery_energy = + sysfs_get_double (obj->native_path, "energy_avg") / 1000000.0; + if (obj->battery_energy == 0) + obj->battery_energy = + sysfs_get_double (obj->native_path, "energy_now") / 1000000.0; + + /* some batteries don't update last_full attribute */ + if (obj->battery_energy > obj->battery_energy_full) + obj->battery_energy_full = obj->battery_energy; + + obj->battery_energy_rate = + fabs (sysfs_get_double (obj->native_path, "current_now") / 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 (obj->battery_energy_rate == 0xffff) + obj->battery_energy_rate = -1; + + /* sanity check to less than 100W */ + if (obj->battery_energy_rate > 100*1000) + obj->battery_energy_rate = -1; + + /* the hardware reporting failed -- try to calculate this */ + if (obj->battery_energy_rate < 0) { + dkp_supply_calculate_battery_rate (supply); + } + + /* charging has a negative rate */ + if (obj->battery_energy_rate > 0 && battery_state == DKP_SOURCE_STATE_CHARGING) + obj->battery_energy_rate *= -1.0; + + /* get a precise percentage */ + obj->battery_percentage = 100.0 * obj->battery_energy / obj->battery_energy_full; + if (obj->battery_percentage < 0) + obj->battery_percentage = 0; + if (obj->battery_percentage > 100.0) + obj->battery_percentage = 100.0; + + /* calculate a quick and dirty time remaining value */ + obj->battery_time_to_empty = -1; + obj->battery_time_to_full = -1; + if (obj->battery_energy_rate > 0) { + if (battery_state == DKP_SOURCE_STATE_DISCHARGING) { + obj->battery_time_to_empty = 3600 * (obj->battery_energy / obj->battery_energy_rate); + } else if (battery_state == DKP_SOURCE_STATE_CHARGING) { + obj->battery_time_to_full = 3600 * ((obj->battery_energy_full - obj->battery_energy) / obj->battery_energy_rate); + } + } + /* check the remaining time is under a set limit, to deal with broken + primary batteries rate */ + if (obj->battery_time_to_empty > (100 * 60 * 60)) + obj->battery_time_to_empty = -1; + if (obj->battery_time_to_full > (100 * 60 * 60)) + obj->battery_time_to_full = -1; + + /* set the old status */ + supply->priv->battery_energy_old = obj->battery_energy; + g_get_current_time (&supply->priv->battery_energy_old_timespec); + + /* we changed state */ + if (obj->battery_state != battery_state) { + supply->priv->battery_energy_old = -1; + obj->battery_state = battery_state; + } + +out: + /* save new history */ + dkp_history_set_state (supply->priv->history, obj->battery_state); + dkp_history_set_charge_data (supply->priv->history, obj->battery_percentage); + dkp_history_set_rate_data (supply->priv->history, obj->battery_energy_rate); + + g_free (status); + return ret; +} + +/** + * dkp_supply_poll_battery: + **/ +static gboolean +dkp_supply_poll_battery (DkpSupply *supply) +{ + gboolean ret; + DkpDevice *device = DKP_DEVICE (supply); + DkpObject *obj = dkp_device_get_obj (device); + + dkp_debug ("No updates on supply %s for 30 seconds; forcing update", obj->native_path); + supply->priv->poll_timer_id = 0; + ret = dkp_supply_refresh (device); + if (ret) + dkp_device_emit_changed (device); + return FALSE; +} + +/** + * dkp_supply_get_stats: + **/ +static GPtrArray * +dkp_supply_get_stats (DkpDevice *device, const gchar *type, guint timespan) +{ + DkpSupply *supply = DKP_SUPPLY (device); + GPtrArray *array = NULL; + + g_return_val_if_fail (DKP_IS_SUPPLY (supply), FALSE); + g_return_val_if_fail (type != NULL, FALSE); + + /* get the correct data */ + if (strcmp (type, "rate") == 0) + array = dkp_history_get_rate_data (supply->priv->history, timespan); + else if (strcmp (type, "charge") == 0) + array = dkp_history_get_charge_data (supply->priv->history, timespan); + + return array; +} + +/** + * dkp_supply_coldplug: + **/ +static gboolean +dkp_supply_coldplug (DkpDevice *device) +{ + DkpSupply *supply = DKP_SUPPLY (device); + DevkitDevice *d; + const gchar *native_path; + DkpObject *obj = dkp_device_get_obj (device); + gchar *id; + + dkp_supply_reset_values (supply); + + /* detect what kind of device we are */ + d = dkp_device_get_d (device); + if (d == NULL) + dkp_error ("could not get device"); + + native_path = devkit_device_get_native_path (d); + if (native_path == NULL) + dkp_error ("could not get native path"); + + if (sysfs_file_exists (native_path, "online")) { + obj->type = DKP_SOURCE_TYPE_LINE_POWER; + } else { + /* this is correct, UPS and CSR are not in the kernel */ + obj->type = DKP_SOURCE_TYPE_BATTERY; + } + + /* get the id so we can load the old history */ + id = dkp_object_get_id (obj); + if (id != NULL) + dkp_history_set_id (supply->priv->history, id); + g_free (id); + + /* coldplug */ + dkp_supply_refresh (device); + return TRUE; +} + +/** + * dkp_supply_refresh: + **/ +static gboolean +dkp_supply_refresh (DkpDevice *device) +{ + gboolean ret; + GTimeVal time; + DkpSupply *supply = DKP_SUPPLY (device); + DkpObject *obj = dkp_device_get_obj (device); + + if (supply->priv->poll_timer_id > 0) { + g_source_remove (supply->priv->poll_timer_id); + supply->priv->poll_timer_id = 0; + } + + g_get_current_time (&time); + obj->update_time = time.tv_sec; + + switch (obj->type) { + case DKP_SOURCE_TYPE_LINE_POWER: + ret = dkp_supply_refresh_line_power (supply); + break; + case DKP_SOURCE_TYPE_BATTERY: + ret = dkp_supply_refresh_battery (supply); + /* Seems that we don't get change uevents from the + * kernel on some BIOS types; set up a timer to poll + * if we are charging or discharging */ + if (obj->battery_state == DKP_SOURCE_STATE_CHARGING || + obj->battery_state == DKP_SOURCE_STATE_DISCHARGING) + supply->priv->poll_timer_id = g_timeout_add_seconds (30, (GSourceFunc) dkp_supply_poll_battery, supply); + break; + default: + g_assert_not_reached (); + break; + } + return ret; +} + +/** + * dkp_supply_init: + **/ +static void +dkp_supply_init (DkpSupply *supply) +{ + supply->priv = DKP_SUPPLY_GET_PRIVATE (supply); + supply->priv->history = dkp_history_new (); +} + +/** + * dkp_supply_finalize: + **/ +static void +dkp_supply_finalize (GObject *object) +{ + DkpSupply *supply; + + g_return_if_fail (object != NULL); + g_return_if_fail (DKP_IS_SUPPLY (object)); + + supply = DKP_SUPPLY (object); + g_return_if_fail (supply->priv != NULL); + + g_object_unref (supply->priv->history); + if (supply->priv->poll_timer_id > 0) + g_source_remove (supply->priv->poll_timer_id); + + G_OBJECT_CLASS (dkp_supply_parent_class)->finalize (object); +} + +/** + * dkp_supply_class_init: + **/ +static void +dkp_supply_class_init (DkpSupplyClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + DkpDeviceClass *device_class = DKP_DEVICE_CLASS (klass); + + object_class->finalize = dkp_supply_finalize; + device_class->get_on_battery = dkp_supply_get_on_battery; + device_class->get_low_battery = dkp_supply_get_low_battery; + device_class->coldplug = dkp_supply_coldplug; + device_class->refresh = dkp_supply_refresh; + device_class->get_stats = dkp_supply_get_stats; + + g_type_class_add_private (klass, sizeof (DkpSupplyPrivate)); +} + +/** + * dkp_supply_new: + **/ +DkpSupply * +dkp_supply_new (void) +{ + return g_object_new (DKP_TYPE_SUPPLY, NULL); +} + diff --git a/src/dkp-supply.h b/src/dkp-supply.h new file mode 100644 index 0000000..1f8c961 --- /dev/null +++ b/src/dkp-supply.h @@ -0,0 +1,56 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 David Zeuthen <david@fubar.dk> + * Copyright (C) 2008 Richard Hughes <richard@hughsie.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __DKP_SUPPLY_H__ +#define __DKP_SUPPLY_H__ + +#include <glib-object.h> +#include "dkp-device.h" + +G_BEGIN_DECLS + +#define DKP_TYPE_SUPPLY (dkp_supply_get_type ()) +#define DKP_SUPPLY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_TYPE_SUPPLY, DkpSupply)) +#define DKP_SUPPLY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_TYPE_SUPPLY, DkpSupplyClass)) +#define DKP_IS_SUPPLY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_TYPE_SUPPLY)) +#define DKP_IS_SUPPLY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_TYPE_SUPPLY)) +#define DKP_SUPPLY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_SUPPLY, DkpSupplyClass)) + +typedef struct DkpSupplyPrivate DkpSupplyPrivate; + +typedef struct +{ + DkpDevice parent; + DkpSupplyPrivate *priv; +} DkpSupply; + +typedef struct +{ + DkpDeviceClass parent_class; +} DkpSupplyClass; + +GType dkp_supply_get_type (void); +DkpSupply *dkp_supply_new (void); + +G_END_DECLS + +#endif /* __DKP_SUPPLY_H__ */ + diff --git a/src/org.freedesktop.DeviceKit.Power.Source.xml b/src/org.freedesktop.DeviceKit.Power.Device.xml index 59e9143..74560f0 100644 --- a/src/org.freedesktop.DeviceKit.Power.Source.xml +++ b/src/org.freedesktop.DeviceKit.Power.Device.xml @@ -1,10 +1,10 @@ <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" [ - <!ENTITY ERROR_GENERAL "org.freedesktop.DeviceKit.Power.Source.GeneralError"> + <!ENTITY ERROR_GENERAL "org.freedesktop.DeviceKit.Power.Device.GeneralError"> ]> <node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> - <interface name="org.freedesktop.DeviceKit.Power.Source"> + <interface name="org.freedesktop.DeviceKit.Power.Device"> <doc:doc> <doc:description> <doc:para> diff --git a/tools/.gitignore b/tools/.gitignore index 173da61..ea46275 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -1,5 +1,6 @@ .deps devkit-power +devkit-power-on-battery *-glue.h *.o *-marshal.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 6519c57..4c88843 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -30,7 +30,7 @@ dkp-marshal.c: $(top_srcdir)/src/dkp-marshal.list dkp-daemon-glue.h: $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.xml Makefile.am dbus-binding-tool --prefix=devkit_power_daemon --mode=glib-client --output=dkp-daemon-glue.h $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.xml -bin_PROGRAMS = devkit-power devkit-battery-power +bin_PROGRAMS = devkit-power devkit-power-on-battery devkit_power_SOURCES = \ dkp-tool.c \ @@ -50,16 +50,16 @@ devkit_power_LDADD = \ $(DEVKIT_POWER_LIBS) \ $(POLKIT_DBUS_LIBS) -devkit_battery_power_SOURCES = \ +devkit_power_on_battery_SOURCES = \ dkp-battery-power.c \ $(BUILT_SOURCES) -devkit_battery_power_CPPFLAGS = \ +devkit_power_on_battery_CPPFLAGS = \ -DG_LOG_DOMAIN=\"devkit-power\" \ $(DISABLE_DEPRECATED) \ $(AM_CPPFLAGS) -devkit_battery_power_LDADD = \ +devkit_power_on_battery_LDADD = \ $(DBUS_GLIB_LIBS) \ $(DEVKIT_POWER_LIBS) \ $(POLKIT_DBUS_LIBS) diff --git a/tools/dkp-client-device.c b/tools/dkp-client-device.c index a3effc9..ad4a245 100644 --- a/tools/dkp-client-device.c +++ b/tools/dkp-client-device.c @@ -146,7 +146,7 @@ dkp_client_device_set_object_path (DkpClientDevice *device, const gchar *object_ /* connect to the correct path for all the other methods */ proxy_source = dbus_g_proxy_new_for_name (device->priv->bus, "org.freedesktop.DeviceKit.Power", - object_path, "org.freedesktop.DeviceKit.Power.Source"); + object_path, "org.freedesktop.DeviceKit.Power.Device"); if (proxy_source == NULL) { dkp_warning ("Couldn't connect to proxy"); goto out; |