mirror of
https://gitlab.freedesktop.org/upower/upower.git
synced 2025-12-27 10:10:04 +01:00
refactor out DkpDevice and DkpSupply so we can add another type of device without a metric ton of copy and paste
This commit is contained in:
parent
6a498f0487
commit
918c35586b
16 changed files with 1258 additions and 1173 deletions
|
|
@ -53,7 +53,7 @@ content_files = \
|
||||||
man/devkit-power-daemon.xml \
|
man/devkit-power-daemon.xml \
|
||||||
man/DeviceKit-power.xml \
|
man/DeviceKit-power.xml \
|
||||||
dbus/org.freedesktop.DeviceKit.Power.ref.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)
|
$(NULL)
|
||||||
|
|
||||||
# Images to copy into HTML directory
|
# Images to copy into HTML directory
|
||||||
|
|
|
||||||
|
|
@ -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
|
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\">" > $@
|
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 >> $@
|
$(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\">" > $@
|
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 >> $@
|
$(XSLTPROC) $(top_srcdir)/doc/dbus/spec-to-docbook.xsl $< | tail -n +2 >> $@
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
</para>
|
</para>
|
||||||
</partintro>
|
</partintro>
|
||||||
<xi:include href="dbus/org.freedesktop.DeviceKit.Power.ref.xml"/>
|
<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>
|
||||||
|
|
||||||
<reference id="tools-fileformats">
|
<reference id="tools-fileformats">
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ DEVKIT_POWER_LIBS = $(top_builddir)/libdevkit-power/libdevkit-power.la
|
||||||
|
|
||||||
BUILT_SOURCES = \
|
BUILT_SOURCES = \
|
||||||
dkp-daemon-glue.h \
|
dkp-daemon-glue.h \
|
||||||
dkp-source-glue.h \
|
dkp-device-glue.h \
|
||||||
dkp-marshal.h dkp-marshal.c
|
dkp-marshal.h dkp-marshal.c
|
||||||
|
|
||||||
dkp-marshal.h: dkp-marshal.list
|
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
|
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
|
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
|
dkp-device-glue.h: org.freedesktop.DeviceKit.Power.Device.xml Makefile.am
|
||||||
dbus-binding-tool --prefix=dkp_source --mode=glib-server --output=dkp-source-glue.h org.freedesktop.DeviceKit.Power.Source.xml
|
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
|
libexec_PROGRAMS = devkit-power-daemon
|
||||||
|
|
||||||
dbusifdir = $(datadir)/dbus-1/interfaces
|
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 = \
|
devkit_power_daemon_SOURCES = \
|
||||||
dkp-daemon.h dkp-daemon.c \
|
dkp-daemon.h dkp-daemon.c \
|
||||||
dkp-device.h dkp-device.c \
|
dkp-device.h dkp-device.c \
|
||||||
dkp-device-list.h dkp-device-list.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 \
|
dkp-history.h dkp-history.c \
|
||||||
sysfs-utils.h sysfs-utils.c \
|
sysfs-utils.h sysfs-utils.c \
|
||||||
main.c \
|
main.c \
|
||||||
|
|
@ -85,7 +85,7 @@ CLEANFILES = $(BUILT_SOURCES)
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
org.freedesktop.DeviceKit.Power.xml \
|
org.freedesktop.DeviceKit.Power.xml \
|
||||||
org.freedesktop.DeviceKit.Power.Source.xml \
|
org.freedesktop.DeviceKit.Power.Device.xml \
|
||||||
dkp-marshal.list \
|
dkp-marshal.list \
|
||||||
95-devkit-power.rules \
|
95-devkit-power.rules \
|
||||||
$(service_in_files) \
|
$(service_in_files) \
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
#include "dkp-debug.h"
|
#include "dkp-debug.h"
|
||||||
#include "dkp-daemon.h"
|
#include "dkp-daemon.h"
|
||||||
#include "dkp-device.h"
|
#include "dkp-device.h"
|
||||||
#include "dkp-source.h"
|
#include "dkp-supply.h"
|
||||||
#include "dkp-device-list.h"
|
#include "dkp-device-list.h"
|
||||||
|
|
||||||
#include "dkp-daemon-glue.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)
|
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:
|
* dkp_daemon_error_quark:
|
||||||
|
|
@ -85,16 +85,12 @@ GQuark
|
||||||
dkp_daemon_error_quark (void)
|
dkp_daemon_error_quark (void)
|
||||||
{
|
{
|
||||||
static GQuark ret = 0;
|
static GQuark ret = 0;
|
||||||
|
if (ret == 0)
|
||||||
if (ret == 0) {
|
|
||||||
ret = g_quark_from_static_string ("dkp_daemon_error");
|
ret = g_quark_from_static_string ("dkp_daemon_error");
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
|
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dkp_daemon_error_get_type:
|
* dkp_daemon_error_get_type:
|
||||||
**/
|
**/
|
||||||
|
|
@ -127,7 +123,7 @@ dkp_daemon_constructor (GType type, guint n_construct_properties, GObjectConstru
|
||||||
DkpDaemon *daemon;
|
DkpDaemon *daemon;
|
||||||
DkpDaemonClass *klass;
|
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));
|
daemon = DKP_DAEMON (G_OBJECT_CLASS (dkp_daemon_parent_class)->constructor (type, n_construct_properties, construct_properties));
|
||||||
return G_OBJECT (daemon);
|
return G_OBJECT (daemon);
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +186,7 @@ dkp_daemon_class_init (DkpDaemonClass *klass)
|
||||||
g_cclosure_marshal_VOID__BOOLEAN,
|
g_cclosure_marshal_VOID__BOOLEAN,
|
||||||
G_TYPE_NONE, 1, G_TYPE_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);
|
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;
|
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);
|
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);
|
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:
|
* gpk_daemon_device_add:
|
||||||
**/
|
**/
|
||||||
static void
|
static gboolean
|
||||||
gpk_daemon_device_add (DkpDaemon *daemon, DevkitDevice *d, gboolean emit_event)
|
gpk_daemon_device_add (DkpDaemon *daemon, DevkitDevice *d, gboolean emit_event)
|
||||||
{
|
{
|
||||||
DkpDevice *device;
|
DkpDevice *device;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
/* does device exist in db? */
|
/* does device exist in db? */
|
||||||
device = dkp_device_list_lookup (daemon->priv->list, d);
|
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));
|
dkp_debug ("treating add event as change event on %s", dkp_device_get_object_path (device));
|
||||||
gpk_daemon_device_changed (daemon, d, FALSE);
|
gpk_daemon_device_changed (daemon, d, FALSE);
|
||||||
} else {
|
} 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
|
/* 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
|
* it's unreffed. So if we ref it, it'll never go away.
|
||||||
* dbus-glib, no cookie for you.
|
|
||||||
*/
|
*/
|
||||||
g_object_weak_ref (G_OBJECT (device), gpk_daemon_device_went_away, daemon);
|
g_object_weak_ref (G_OBJECT (device), gpk_daemon_device_went_away, daemon);
|
||||||
dkp_device_list_insert (daemon->priv->list, d, device);
|
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));
|
dkp_device_get_object_path (device));
|
||||||
}
|
}
|
||||||
} else {
|
} 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 *devices;
|
||||||
GList *l;
|
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 ();
|
daemon->priv->list = dkp_device_list_new ();
|
||||||
if (!gpk_daemon_register_power_daemon (DKP_DAEMON (daemon))) {
|
if (!gpk_daemon_register_power_daemon (DKP_DAEMON (daemon))) {
|
||||||
|
|
@ -844,3 +884,4 @@ out:
|
||||||
polkit_caller_unref (pk_caller);
|
polkit_caller_unref (pk_caller);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define DKP_SOURCE_TYPE_DAEMON (dkp_daemon_get_type ())
|
#define DKP_TYPE_DAEMON (dkp_daemon_get_type ())
|
||||||
#define DKP_DAEMON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_SOURCE_TYPE_DAEMON, DkpDaemon))
|
#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_SOURCE_TYPE_DAEMON, DkpDaemonClass))
|
#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_SOURCE_TYPE_DAEMON))
|
#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_SOURCE_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_SOURCE_TYPE_DAEMON, DkpDaemonClass))
|
#define DKP_DAEMON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_DAEMON, DkpDaemonClass))
|
||||||
|
|
||||||
typedef struct DkpDaemonPrivate DkpDaemonPrivate;
|
typedef struct DkpDaemonPrivate DkpDaemonPrivate;
|
||||||
|
|
||||||
|
|
|
||||||
608
src/dkp-device.c
608
src/dkp-device.c
|
|
@ -1,6 +1,7 @@
|
||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -35,30 +36,184 @@
|
||||||
|
|
||||||
#include "sysfs-utils.h"
|
#include "sysfs-utils.h"
|
||||||
#include "dkp-debug.h"
|
#include "dkp-debug.h"
|
||||||
|
#include "dkp-supply.h"
|
||||||
#include "dkp-device.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"
|
||||||
|
|
||||||
static void dkp_device_class_init (DkpDeviceClass *klass);
|
struct DkpDevicePrivate
|
||||||
static void dkp_device_init (DkpDevice *seat);
|
{
|
||||||
|
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 guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
G_DEFINE_TYPE (DkpDevice, dkp_device, G_TYPE_OBJECT)
|
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_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_SOURCE_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_class_init:
|
* dkp_device_error_quark:
|
||||||
**/
|
**/
|
||||||
static void
|
GQuark
|
||||||
dkp_device_class_init (DkpDeviceClass *klass)
|
dkp_device_error_quark (void)
|
||||||
{
|
{
|
||||||
|
static GQuark ret = 0;
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = g_quark_from_static_string ("dkp_device_error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dkp_device_error_get_type:
|
||||||
|
**/
|
||||||
|
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
|
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,46 +222,9 @@ dkp_device_init (DkpDevice *device)
|
||||||
void
|
void
|
||||||
dkp_device_removed (DkpDevice *device)
|
dkp_device_removed (DkpDevice *device)
|
||||||
{
|
{
|
||||||
DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device);
|
//DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device);
|
||||||
klass->removed (device);
|
//klass->removed (device);
|
||||||
}
|
dkp_warning ("do something here?");
|
||||||
|
|
||||||
/**
|
|
||||||
* dkp_device_new:
|
|
||||||
**/
|
|
||||||
DkpDevice *
|
|
||||||
dkp_device_new (DkpDaemon *daemon, DevkitDevice *d)
|
|
||||||
{
|
|
||||||
const gchar *subsys;
|
|
||||||
DkpDevice *device;
|
|
||||||
|
|
||||||
device = NULL;
|
|
||||||
|
|
||||||
subsys = devkit_device_get_subsystem (d);
|
|
||||||
if (strcmp (subsys, "power_supply") == 0) {
|
|
||||||
device = DKP_DEVICE (dkp_source_new (daemon, d));
|
|
||||||
}
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dkp_device_get_object_path:
|
|
||||||
**/
|
|
||||||
const gchar *
|
|
||||||
dkp_device_get_object_path (DkpDevice *device)
|
|
||||||
{
|
|
||||||
DkpDeviceClass *klass = DKP_DEVICE_GET_CLASS (device);
|
|
||||||
return klass->get_object_path (device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -129,3 +247,393 @@ dkp_device_get_low_battery (DkpDevice *device, gboolean *low_battery)
|
||||||
return klass->get_low_battery (device, low_battery);
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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_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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dkp_device_get_object_path:
|
||||||
|
**/
|
||||||
|
const gchar *
|
||||||
|
dkp_device_get_object_path (DkpDevice *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_emit_changed:
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
dkp_device_emit_changed (DkpDevice *device)
|
||||||
|
{
|
||||||
|
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_compute_object_path_from_basename:
|
||||||
|
**/
|
||||||
|
static char *
|
||||||
|
dkp_device_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 ("/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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,21 +25,26 @@
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <polkit-dbus/polkit-dbus.h>
|
#include <polkit-dbus/polkit-dbus.h>
|
||||||
#include <devkit-gobject.h>
|
#include <devkit-gobject.h>
|
||||||
|
#include <dbus/dbus-glib.h>
|
||||||
|
#include "dkp-object.h"
|
||||||
|
|
||||||
#include "dkp-daemon.h"
|
#include "dkp-daemon.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define DKP_SOURCE_TYPE_DEVICE (dkp_device_get_type ())
|
#define DKP_TYPE_DEVICE (dkp_device_get_type ())
|
||||||
#define DKP_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_SOURCE_TYPE_DEVICE, DkpDevice))
|
#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_SOURCE_TYPE_DEVICE, DkpDeviceClass))
|
#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_SOURCE_TYPE_DEVICE))
|
#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_SOURCE_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_SOURCE_TYPE_DEVICE, DkpDeviceClass))
|
#define DKP_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_DEVICE, DkpDeviceClass))
|
||||||
|
|
||||||
|
typedef struct DkpDevicePrivate DkpDevicePrivate;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
DkpDevicePrivate *priv;
|
||||||
} DkpDevice;
|
} DkpDevice;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -47,29 +52,53 @@ typedef struct
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
/* vtable */
|
/* vtable */
|
||||||
gboolean (*changed) (DkpDevice *device,
|
gboolean (*coldplug) (DkpDevice *device);
|
||||||
DevkitDevice *d,
|
gboolean (*refresh) (DkpDevice *device);
|
||||||
gboolean synthesized);
|
const gchar *(*get_id) (DkpDevice *device);
|
||||||
void (*removed) (DkpDevice *device);
|
|
||||||
const gchar *(*get_object_path) (DkpDevice *device);
|
|
||||||
gboolean (*get_on_battery) (DkpDevice *device,
|
gboolean (*get_on_battery) (DkpDevice *device,
|
||||||
gboolean *on_battery);
|
gboolean *on_battery);
|
||||||
gboolean (*get_low_battery) (DkpDevice *device,
|
gboolean (*get_low_battery) (DkpDevice *device,
|
||||||
gboolean *low_battery);
|
gboolean *low_battery);
|
||||||
|
GPtrArray *(*get_stats) (DkpDevice *device,
|
||||||
|
const gchar *type,
|
||||||
|
guint timespan);
|
||||||
} DkpDeviceClass;
|
} 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);
|
GType dkp_device_get_type (void);
|
||||||
DkpDevice *dkp_device_new (DkpDaemon *daemon,
|
gboolean dkp_device_coldplug (DkpDevice *device,
|
||||||
|
DkpDaemon *daemon,
|
||||||
DevkitDevice *d);
|
DevkitDevice *d);
|
||||||
gboolean dkp_device_changed (DkpDevice *device,
|
gboolean dkp_device_changed (DkpDevice *device,
|
||||||
DevkitDevice *d,
|
DevkitDevice *d,
|
||||||
gboolean synthesized);
|
gboolean synthesized);
|
||||||
void dkp_device_removed (DkpDevice *device);
|
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);
|
const gchar *dkp_device_get_object_path (DkpDevice *device);
|
||||||
gboolean dkp_device_get_on_battery (DkpDevice *device,
|
gboolean dkp_device_get_on_battery (DkpDevice *device,
|
||||||
gboolean *on_battery);
|
gboolean *on_battery);
|
||||||
gboolean dkp_device_get_low_battery (DkpDevice *device,
|
gboolean dkp_device_get_low_battery (DkpDevice *device,
|
||||||
gboolean *low_battery);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
||||||
991
src/dkp-source.c
991
src/dkp-source.c
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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__ */
|
|
||||||
520
src/dkp-supply.c
Normal file
520
src/dkp-supply.c
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
56
src/dkp-supply.h
Normal file
56
src/dkp-supply.h
Normal file
|
|
@ -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__ */
|
||||||
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<!DOCTYPE node PUBLIC
|
<!DOCTYPE node PUBLIC
|
||||||
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" [
|
"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">
|
<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:doc>
|
||||||
<doc:description>
|
<doc:description>
|
||||||
<doc:para>
|
<doc:para>
|
||||||
1
tools/.gitignore
vendored
1
tools/.gitignore
vendored
|
|
@ -1,5 +1,6 @@
|
||||||
.deps
|
.deps
|
||||||
devkit-power
|
devkit-power
|
||||||
|
devkit-power-on-battery
|
||||||
*-glue.h
|
*-glue.h
|
||||||
*.o
|
*.o
|
||||||
*-marshal.c
|
*-marshal.c
|
||||||
|
|
|
||||||
|
|
@ -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
|
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
|
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 = \
|
devkit_power_SOURCES = \
|
||||||
dkp-tool.c \
|
dkp-tool.c \
|
||||||
|
|
@ -50,16 +50,16 @@ devkit_power_LDADD = \
|
||||||
$(DEVKIT_POWER_LIBS) \
|
$(DEVKIT_POWER_LIBS) \
|
||||||
$(POLKIT_DBUS_LIBS)
|
$(POLKIT_DBUS_LIBS)
|
||||||
|
|
||||||
devkit_battery_power_SOURCES = \
|
devkit_power_on_battery_SOURCES = \
|
||||||
dkp-battery-power.c \
|
dkp-battery-power.c \
|
||||||
$(BUILT_SOURCES)
|
$(BUILT_SOURCES)
|
||||||
|
|
||||||
devkit_battery_power_CPPFLAGS = \
|
devkit_power_on_battery_CPPFLAGS = \
|
||||||
-DG_LOG_DOMAIN=\"devkit-power\" \
|
-DG_LOG_DOMAIN=\"devkit-power\" \
|
||||||
$(DISABLE_DEPRECATED) \
|
$(DISABLE_DEPRECATED) \
|
||||||
$(AM_CPPFLAGS)
|
$(AM_CPPFLAGS)
|
||||||
|
|
||||||
devkit_battery_power_LDADD = \
|
devkit_power_on_battery_LDADD = \
|
||||||
$(DBUS_GLIB_LIBS) \
|
$(DBUS_GLIB_LIBS) \
|
||||||
$(DEVKIT_POWER_LIBS) \
|
$(DEVKIT_POWER_LIBS) \
|
||||||
$(POLKIT_DBUS_LIBS)
|
$(POLKIT_DBUS_LIBS)
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
/* 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",
|
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) {
|
if (proxy_source == NULL) {
|
||||||
dkp_warning ("Couldn't connect to proxy");
|
dkp_warning ("Couldn't connect to proxy");
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue