daemon: port UpDevice to GDBus

This commit is contained in:
Cosimo Cecchi 2015-05-30 13:41:37 -07:00 committed by Richard Hughes
parent e7e9156fe9
commit 4e2f06d9eb
3 changed files with 170 additions and 493 deletions

View file

@ -36,9 +36,10 @@ AM_CPPFLAGS = \
UPOWER_LIBS = $(top_builddir)/libupower-glib/libupower-glib.la
BUILT_SOURCES = \
up-device-glue.h \
up-daemon-generated.h \
up-daemon-generated.c \
up-device-generated.h \
up-device-generated.c \
up-kbd-backlight-generated.h \
up-kbd-backlight-generated.c \
up-wakeups-generated.h \
@ -59,8 +60,12 @@ up-daemon-generated.h: org.freedesktop.UPower.xml Makefile.am
--annotate "org.freedesktop.UPower" "org.gtk.GDBus.C.Name" ExportedDaemon \
$(srcdir)/org.freedesktop.UPower.xml
up-device-glue.h: org.freedesktop.UPower.Device.xml Makefile.am
dbus-binding-tool --prefix=up_device --mode=glib-server --output=up-device-glue.h $(srcdir)/org.freedesktop.UPower.Device.xml
up-device-generated.h: org.freedesktop.UPower.Device.xml Makefile.am
$(AM_V_GEN) gdbus-codegen --interface-prefix org.freedesktop.UPower.Device. \
--generate-c-code up-device-generated \
--c-namespace Up \
--annotate "org.freedesktop.UPower.Device" "org.gtk.GDBus.C.Name" ExportedDevice \
$(srcdir)/org.freedesktop.UPower.Device.xml
up-kbd-backlight-generated.h: org.freedesktop.UPower.KbdBacklight.xml Makefile.am
$(AM_V_GEN) gdbus-codegen --interface-prefix org.freedesktop.UPower.KbdBacklight. \

View file

@ -29,8 +29,6 @@
#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 "up-native.h"
#include "up-device.h"
@ -38,50 +36,16 @@
#include "up-history-item.h"
#include "up-stats-item.h"
#include "up-marshal.h"
#include "up-device-glue.h"
#include "up-device-generated.h"
struct UpDevicePrivate
{
gchar *object_path;
DBusGConnection *system_bus_connection;
UpExportedDevice *skeleton;
UpDaemon *daemon;
UpHistory *history;
GObject *native;
gboolean has_ever_refresh;
/* PropertiesChanged to be emitted */
GHashTable *changed_props;
guint props_idle_id;
/* properties */
guint64 update_time;
gchar *vendor;
gchar *model;
gchar *serial;
gchar *native_path;
gboolean power_supply;
gboolean online;
gboolean is_present;
gboolean is_rechargeable;
gboolean has_history;
gboolean has_statistics;
UpDeviceKind type;
UpDeviceState state;
UpDeviceTechnology technology;
gdouble capacity; /* percent */
gdouble energy; /* Watt Hours */
gdouble energy_empty; /* Watt Hours */
gdouble energy_full; /* Watt Hours */
gdouble energy_full_design; /* Watt Hours */
gdouble energy_rate; /* Watts */
gdouble voltage; /* Volts */
gdouble luminosity; /* Lux */
gint64 time_to_empty; /* seconds */
gint64 time_to_full; /* seconds */
gdouble percentage; /* percent */
gdouble temperature; /* degrees C */
UpDeviceLevel warning_level; /* computed */
const gchar *icon_name; /* computed */
};
static gboolean up_device_register_device (UpDevice *device);
@ -121,55 +85,9 @@ enum {
G_DEFINE_TYPE (UpDevice, up_device, G_TYPE_OBJECT)
#define UP_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UP_TYPE_DEVICE, UpDevicePrivate))
#define UP_DBUS_STRUCT_UINT_DOUBLE_UINT (dbus_g_type_get_struct ("GValueArray", \
G_TYPE_UINT, G_TYPE_DOUBLE, G_TYPE_UINT, G_TYPE_INVALID))
#define UP_DBUS_STRUCT_DOUBLE_DOUBLE (dbus_g_type_get_struct ("GValueArray", \
G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_INVALID))
#define UP_DEVICES_DBUS_PATH "/org/freedesktop/UPower/devices"
static void up_device_queue_changed_property (UpDevice *device,
const gchar *property,
GVariant *value);
/**
* up_device_error_quark:
**/
GQuark
up_device_error_quark (void)
{
static GQuark ret = 0;
if (ret == 0) {
ret = g_quark_from_static_string ("up_device_error");
}
return ret;
}
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
/**
* up_device_error_get_type:
**/
GType
up_device_error_get_type (void)
{
static GType etype = 0;
if (etype == 0)
{
static const GEnumValue values[] =
{
ENUM_ENTRY (UP_DEVICE_ERROR_GENERAL, "GeneralError"),
{ 0, 0, 0 }
};
g_assert (UP_DEVICE_NUM_ERRORS == G_N_ELEMENTS (values) - 1);
etype = g_enum_register_static ("UpDeviceError", values);
}
return etype;
}
/* This needs to be called when one of those properties changes:
* state
* power_supply
@ -188,19 +106,14 @@ update_warning_level (UpDevice *device)
return;
warning_level = up_daemon_compute_warning_level (device->priv->daemon,
device->priv->state,
device->priv->type,
device->priv->power_supply,
device->priv->percentage,
device->priv->time_to_empty);
up_exported_device_get_state (device->priv->skeleton),
up_exported_device_get_type_ (device->priv->skeleton),
up_exported_device_get_power_supply (device->priv->skeleton),
up_exported_device_get_percentage (device->priv->skeleton),
up_exported_device_get_time_to_empty (device->priv->skeleton));
if (warning_level == device->priv->warning_level)
return;
device->priv->warning_level = warning_level;
up_exported_device_set_warning_level (device->priv->skeleton, warning_level);
g_object_notify (G_OBJECT (device), "warning-level");
up_device_queue_changed_property (device, "warning-level", g_variant_new_uint32 (device->priv->warning_level));
}
static const gchar *
@ -228,15 +141,15 @@ update_icon_name (UpDevice *device)
const gchar *icon_name = NULL;
/* get the icon from some simple rules */
if (device->priv->type == UP_DEVICE_KIND_LINE_POWER) {
if (up_exported_device_get_type_ (device->priv->skeleton) == UP_DEVICE_KIND_LINE_POWER) {
icon_name = "ac-adapter-symbolic";
} else {
if (!device->priv->is_present) {
if (!up_exported_device_get_is_present (device->priv->skeleton)) {
icon_name = "battery-missing-symbolic";
} else {
switch (device->priv->state) {
switch (up_exported_device_get_state (device->priv->skeleton)) {
case UP_DEVICE_STATE_EMPTY:
icon_name = "battery-empty-symbolic";
break;
@ -245,11 +158,11 @@ update_icon_name (UpDevice *device)
break;
case UP_DEVICE_STATE_CHARGING:
case UP_DEVICE_STATE_PENDING_CHARGE:
icon_name = get_device_charge_icon (device->priv->percentage, TRUE);
icon_name = get_device_charge_icon (up_exported_device_get_percentage (device->priv->skeleton), TRUE);
break;
case UP_DEVICE_STATE_DISCHARGING:
case UP_DEVICE_STATE_PENDING_DISCHARGE:
icon_name = get_device_charge_icon (device->priv->percentage, FALSE);
icon_name = get_device_charge_icon (up_exported_device_get_percentage (device->priv->skeleton), FALSE);
break;
default:
icon_name = "battery-missing-symbolic";
@ -257,64 +170,8 @@ update_icon_name (UpDevice *device)
}
}
if (g_strcmp0 (icon_name, device->priv->icon_name) == 0)
return;
device->priv->icon_name = icon_name;
up_exported_device_set_icon_name (device->priv->skeleton, icon_name);
g_object_notify (G_OBJECT (device), "icon-name");
up_device_queue_changed_property (device, "icon-name", g_variant_new_string (device->priv->icon_name));
}
static gboolean
changed_props_idle_cb (gpointer user_data)
{
UpDevice *device = user_data;
/* D-Bus */
up_daemon_emit_properties_changed (device->priv->system_bus_connection,
device->priv->object_path,
"org.freedesktop.UPower.Device",
device->priv->changed_props);
g_clear_pointer (&device->priv->changed_props, g_hash_table_unref);
device->priv->props_idle_id = 0;
return G_SOURCE_REMOVE;
}
/**
* up_device_queue_changed_property:
**/
static void
up_device_queue_changed_property (UpDevice *device,
const gchar *property,
GVariant *value)
{
gchar *dbus_prop;
gchar **items;
guint i;
g_return_if_fail (UP_IS_DEVICE (device));
if (device->priv->system_bus_connection == NULL)
return;
if (!device->priv->changed_props) {
device->priv->changed_props = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) g_variant_unref);
}
items = g_strsplit (property, "-", -1);
for (i = 0; items[i] != NULL; i++)
*items[i] = g_ascii_toupper (*items[i]);
dbus_prop = g_strjoinv (NULL, items);
g_strfreev (items);
g_hash_table_insert (device->priv->changed_props,
dbus_prop, value);
if (device->priv->props_idle_id == 0)
device->priv->props_idle_id = g_idle_add (changed_props_idle_cb, device);
}
/**
@ -324,95 +181,7 @@ static void
up_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
UpDevice *device = UP_DEVICE (object);
switch (prop_id) {
case PROP_NATIVE_PATH:
g_value_set_string (value, device->priv->native_path);
break;
case PROP_VENDOR:
g_value_set_string (value, device->priv->vendor);
break;
case PROP_MODEL:
g_value_set_string (value, device->priv->model);
break;
case PROP_SERIAL:
g_value_set_string (value, device->priv->serial);
break;
case PROP_UPDATE_TIME:
g_value_set_uint64 (value, device->priv->update_time);
break;
case PROP_TYPE:
g_value_set_uint (value, device->priv->type);
break;
case PROP_POWER_SUPPLY:
g_value_set_boolean (value, device->priv->power_supply);
break;
case PROP_ONLINE:
g_value_set_boolean (value, device->priv->online);
break;
case PROP_IS_PRESENT:
g_value_set_boolean (value, device->priv->is_present);
break;
case PROP_IS_RECHARGEABLE:
g_value_set_boolean (value, device->priv->is_rechargeable);
break;
case PROP_HAS_HISTORY:
g_value_set_boolean (value, device->priv->has_history);
break;
case PROP_HAS_STATISTICS:
g_value_set_boolean (value, device->priv->has_statistics);
break;
case PROP_STATE:
g_value_set_uint (value, device->priv->state);
break;
case PROP_CAPACITY:
g_value_set_double (value, device->priv->capacity);
break;
case PROP_ENERGY:
g_value_set_double (value, device->priv->energy);
break;
case PROP_ENERGY_EMPTY:
g_value_set_double (value, device->priv->energy_empty);
break;
case PROP_ENERGY_FULL:
g_value_set_double (value, device->priv->energy_full);
break;
case PROP_ENERGY_FULL_DESIGN:
g_value_set_double (value, device->priv->energy_full_design);
break;
case PROP_ENERGY_RATE:
g_value_set_double (value, device->priv->energy_rate);
break;
case PROP_VOLTAGE:
g_value_set_double (value, device->priv->voltage);
break;
case PROP_LUMINOSITY:
g_value_set_double (value, device->priv->luminosity);
break;
case PROP_TIME_TO_EMPTY:
g_value_set_int64 (value, device->priv->time_to_empty);
break;
case PROP_TIME_TO_FULL:
g_value_set_int64 (value, device->priv->time_to_full);
break;
case PROP_PERCENTAGE:
g_value_set_double (value, device->priv->percentage);
break;
case PROP_TEMPERATURE:
g_value_set_double (value, device->priv->temperature);
break;
case PROP_TECHNOLOGY:
g_value_set_uint (value, device->priv->technology);
break;
case PROP_WARNING_LEVEL:
g_value_set_uint (value, device->priv->warning_level);
break;
case PROP_ICON_NAME:
g_value_set_string (value, device->priv->icon_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
g_object_get_property (G_OBJECT (device->priv->skeleton), pspec->name, value);
}
/**
@ -423,110 +192,31 @@ up_device_set_property (GObject *object, guint prop_id, const GValue *value, GPa
{
UpDevice *device = UP_DEVICE (object);
g_object_set_property (G_OBJECT (device->priv->skeleton), pspec->name, value);
switch (prop_id) {
case PROP_NATIVE_PATH:
g_free (device->priv->native_path);
device->priv->native_path = g_strdup (g_value_get_string (value));
break;
case PROP_VENDOR:
g_free (device->priv->vendor);
device->priv->vendor = g_strdup (g_value_get_string (value));
break;
case PROP_MODEL:
g_free (device->priv->model);
device->priv->model = g_strdup (g_value_get_string (value));
break;
case PROP_SERIAL:
g_free (device->priv->serial);
device->priv->serial = g_strdup (g_value_get_string (value));
break;
case PROP_UPDATE_TIME:
device->priv->update_time = g_value_get_uint64 (value);
break;
case PROP_TYPE:
device->priv->type = g_value_get_uint (value);
update_icon_name (device);
break;
case PROP_POWER_SUPPLY:
device->priv->power_supply = g_value_get_boolean (value);
update_warning_level (device);
break;
case PROP_ONLINE:
device->priv->online = g_value_get_boolean (value);
break;
case PROP_IS_PRESENT:
device->priv->is_present = g_value_get_boolean (value);
update_icon_name (device);
break;
case PROP_IS_RECHARGEABLE:
device->priv->is_rechargeable = g_value_get_boolean (value);
break;
case PROP_HAS_HISTORY:
device->priv->has_history = g_value_get_boolean (value);
break;
case PROP_HAS_STATISTICS:
device->priv->has_statistics = g_value_get_boolean (value);
break;
case PROP_STATE:
device->priv->state = g_value_get_uint (value);
update_warning_level (device);
update_icon_name (device);
break;
case PROP_CAPACITY:
device->priv->capacity = g_value_get_double (value);
break;
case PROP_ENERGY:
device->priv->energy = g_value_get_double (value);
break;
case PROP_ENERGY_EMPTY:
device->priv->energy_empty = g_value_get_double (value);
break;
case PROP_ENERGY_FULL:
device->priv->energy_full = g_value_get_double (value);
break;
case PROP_ENERGY_FULL_DESIGN:
device->priv->energy_full_design = g_value_get_double (value);
break;
case PROP_ENERGY_RATE:
device->priv->energy_rate = g_value_get_double (value);
break;
case PROP_VOLTAGE:
device->priv->voltage = g_value_get_double (value);
break;
case PROP_LUMINOSITY:
device->priv->luminosity = g_value_get_double (value);
break;
case PROP_TIME_TO_EMPTY:
device->priv->time_to_empty = g_value_get_int64 (value);
update_warning_level (device);
break;
case PROP_TIME_TO_FULL:
device->priv->time_to_full = g_value_get_int64 (value);
break;
case PROP_PERCENTAGE:
device->priv->percentage = g_value_get_double (value);
update_warning_level (device);
update_icon_name (device);
break;
case PROP_TEMPERATURE:
device->priv->temperature = g_value_get_double (value);
break;
case PROP_TECHNOLOGY:
device->priv->technology = g_value_get_uint (value);
break;
case PROP_WARNING_LEVEL:
device->priv->warning_level = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
return;
break;
}
if (G_VALUE_TYPE (value) == G_TYPE_STRING &&
g_value_get_string (value) == NULL)
up_device_queue_changed_property (device, pspec->name, g_variant_new_string (""));
else
up_device_queue_changed_property (device, pspec->name, dbus_g_value_build_g_variant (value));
}
/**
@ -575,31 +265,42 @@ up_device_get_id (UpDevice *device)
{
GString *string;
gchar *id = NULL;
gdouble energy_full_design;
const char *model;
const char *serial;
const char *vendor;
UpDeviceKind type;
type = up_exported_device_get_type_ (device->priv->skeleton);
energy_full_design = up_exported_device_get_energy_full_design (device->priv->skeleton);
model = up_exported_device_get_model (device->priv->skeleton);
serial = up_exported_device_get_serial (device->priv->skeleton);
vendor = up_exported_device_get_vendor (device->priv->skeleton);
/* line power */
if (device->priv->type == UP_DEVICE_KIND_LINE_POWER) {
if (type == UP_DEVICE_KIND_LINE_POWER) {
goto out;
/* batteries */
} else if (device->priv->type == UP_DEVICE_KIND_BATTERY) {
} else if (type == UP_DEVICE_KIND_BATTERY) {
/* we don't have an ID if we are not present */
if (!device->priv->is_present)
if (!up_exported_device_get_is_present (device->priv->skeleton))
goto out;
string = g_string_new ("");
/* in an ideal world, model-capacity-serial */
if (device->priv->model != NULL && strlen (device->priv->model) > 2) {
g_string_append (string, device->priv->model);
if (model != NULL && strlen (model) > 2) {
g_string_append (string, model);
g_string_append_c (string, '-');
}
if (device->priv->energy_full_design > 0) {
if (energy_full_design > 0) {
/* FIXME: this may not be stable if we are using voltage_now */
g_string_append_printf (string, "%i", (guint) device->priv->energy_full_design);
g_string_append_printf (string, "%i", (guint) energy_full_design);
g_string_append_c (string, '-');
}
if (device->priv->serial != NULL && strlen (device->priv->serial) > 2) {
g_string_append (string, device->priv->serial);
if (serial != NULL && strlen (serial) > 2) {
g_string_append (string, serial);
g_string_append_c (string, '-');
}
@ -618,16 +319,16 @@ up_device_get_id (UpDevice *device)
} else {
/* generic fallback, get what data we can */
string = g_string_new ("");
if (device->priv->vendor != NULL) {
g_string_append (string, device->priv->vendor);
if (vendor != NULL) {
g_string_append (string, vendor);
g_string_append_c (string, '-');
}
if (device->priv->model != NULL) {
g_string_append (string, device->priv->model);
if (model != NULL) {
g_string_append (string, model);
g_string_append_c (string, '-');
}
if (device->priv->serial != NULL) {
g_string_append (string, device->priv->serial);
if (serial != NULL) {
g_string_append (string, serial);
g_string_append_c (string, '-');
}
@ -683,13 +384,14 @@ up_device_coldplug (UpDevice *device, UpDaemon *daemon, GObject *native)
device->priv->daemon = g_object_ref (daemon);
native_path = up_native_get_native_path (native);
device->priv->native_path = g_strdup (native_path);
up_exported_device_set_native_path (device->priv->skeleton, native_path);
g_object_notify (G_OBJECT (device), "native-path");
/* coldplug source */
if (klass->coldplug != NULL) {
ret = klass->coldplug (device);
if (!ret) {
g_debug ("failed to coldplug %s", device->priv->native_path);
g_debug ("failed to coldplug %s", native_path);
goto bail;
}
}
@ -697,7 +399,7 @@ up_device_coldplug (UpDevice *device, UpDaemon *daemon, GObject *native)
/* force a refresh, although failure isn't fatal */
ret = up_device_refresh_internal (device);
if (!ret) {
g_debug ("failed to refresh %s", device->priv->native_path);
g_debug ("failed to refresh %s", native_path);
/* TODO: refresh should really have separate
* success _and_ changed parameters */
@ -714,7 +416,7 @@ out:
/* only put on the bus if we succeeded */
ret = up_device_register_device (device);
if (!ret) {
g_warning ("failed to register device %s", device->priv->native_path);
g_warning ("failed to register device %s", native_path);
goto out;
}
bail:
@ -737,42 +439,25 @@ up_device_unplug (UpDevice *device)
}
}
/**
* up_device_register_display_device:
**/
gboolean
up_device_register_display_device (UpDevice *device,
UpDaemon *daemon)
{
g_return_val_if_fail (UP_IS_DEVICE (device), FALSE);
device->priv->daemon = g_object_ref (daemon);
device->priv->object_path = g_build_filename (UP_DEVICES_DBUS_PATH, "DisplayDevice", NULL);
dbus_g_connection_register_g_object (device->priv->system_bus_connection,
device->priv->object_path, G_OBJECT (device));
return TRUE;
}
/**
* up_device_get_statistics:
**/
gboolean
up_device_get_statistics (UpDevice *device, const gchar *type, DBusGMethodInvocation *context)
static gboolean
up_device_get_statistics (UpExportedDevice *skeleton,
GDBusMethodInvocation *invocation,
const gchar *type,
UpDevice *device)
{
GError *error = NULL;
GPtrArray *array = NULL;
GPtrArray *complex;
UpStatsItem *item;
GValue *value;
guint i;
g_return_val_if_fail (UP_IS_DEVICE (device), FALSE);
g_return_val_if_fail (type != NULL, FALSE);
GVariantBuilder builder;
/* doesn't even try to support this */
if (!device->priv->has_statistics) {
error = g_error_new (UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL, "device does not support getting stats");
dbus_g_method_return_error (context, error);
if (!up_exported_device_get_has_statistics (skeleton)) {
g_dbus_method_invocation_return_error_literal (invocation,
UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL,
"device does not support getting stats");
goto out;
}
@ -784,64 +469,59 @@ up_device_get_statistics (UpDevice *device, const gchar *type, DBusGMethodInvoca
/* maybe the device doesn't support histories */
if (array == NULL) {
error = g_error_new (UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL, "device has no statistics");
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_return_error_literal (invocation,
UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL,
"device has no statistics");
goto out;
}
/* always 101 items of data */
if (array->len != 101) {
error = g_error_new (UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL, "statistics invalid as have %i items", array->len);
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_return_error (invocation,
UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL,
"statistics invalid as have %i items", array->len);
goto out;
}
/* copy data to dbus struct */
complex = g_ptr_array_new_full (array->len, (GDestroyNotify) g_value_array_free);
for (i=0; i<array->len; i++) {
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(dd)"));
for (i = 0; i < array->len; i++) {
item = (UpStatsItem *) g_ptr_array_index (array, i);
value = g_new0 (GValue, 1);
g_value_init (value, UP_DBUS_STRUCT_DOUBLE_DOUBLE);
g_value_take_boxed (value, dbus_g_type_specialized_construct (UP_DBUS_STRUCT_DOUBLE_DOUBLE));
dbus_g_type_struct_set (value,
0, up_stats_item_get_value (item),
1, up_stats_item_get_accuracy (item),
G_MAXUINT);
g_ptr_array_add (complex, g_value_get_boxed (value));
g_free (value);
g_variant_builder_add (&builder, "(dd)",
up_stats_item_get_value (item),
up_stats_item_get_accuracy (item));
}
dbus_g_method_return (context, complex);
g_ptr_array_unref (complex);
up_exported_device_complete_get_statistics (skeleton, invocation,
g_variant_builder_end (&builder));
out:
if (array != NULL)
g_ptr_array_unref (array);
if (error != NULL)
g_error_free (error);
return TRUE;
}
/**
* up_device_get_history:
**/
gboolean
up_device_get_history (UpDevice *device, const gchar *type_string, guint timespan, guint resolution, DBusGMethodInvocation *context)
static gboolean
up_device_get_history (UpExportedDevice *skeleton,
GDBusMethodInvocation *invocation,
const gchar *type_string,
guint timespan,
guint resolution,
UpDevice *device)
{
GError *error = NULL;
GPtrArray *array = NULL;
GPtrArray *complex;
UpHistoryItem *item;
GValue *value;
guint i;
UpHistoryType type = UP_HISTORY_TYPE_UNKNOWN;
g_return_val_if_fail (UP_IS_DEVICE (device), FALSE);
g_return_val_if_fail (type_string != NULL, FALSE);
GVariantBuilder builder;
/* doesn't even try to support this */
if (!device->priv->has_history) {
error = g_error_new (UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL, "device does not support getting history");
dbus_g_method_return_error (context, error);
if (!up_exported_device_get_has_history (skeleton)) {
g_dbus_method_invocation_return_error_literal (invocation,
UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL,
"device does not support getting history");
goto out;
}
@ -861,34 +541,75 @@ up_device_get_history (UpDevice *device, const gchar *type_string, guint timespa
/* maybe the device doesn't have any history */
if (array == NULL) {
error = g_error_new (UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL, "device has no history");
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_return_error_literal (invocation,
UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL,
"device has no history");
goto out;
}
/* copy data to dbus struct */
complex = g_ptr_array_new_full (array->len, (GDestroyNotify) g_value_array_free);
for (i=0; i<array->len; i++) {
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(udu)"));
for (i = 0; i < array->len; i++) {
item = (UpHistoryItem *) g_ptr_array_index (array, i);
value = g_new0 (GValue, 1);
g_value_init (value, UP_DBUS_STRUCT_UINT_DOUBLE_UINT);
g_value_take_boxed (value, dbus_g_type_specialized_construct (UP_DBUS_STRUCT_UINT_DOUBLE_UINT));
dbus_g_type_struct_set (value,
0, up_history_item_get_time (item),
1, up_history_item_get_value (item),
2, up_history_item_get_state (item),
G_MAXUINT);
g_ptr_array_add (complex, g_value_get_boxed (value));
g_free (value);
g_variant_builder_add (&builder, "(udu)",
up_history_item_get_time (item),
up_history_item_get_value (item),
up_history_item_get_state (item));
}
dbus_g_method_return (context, complex);
g_ptr_array_unref (complex);
up_exported_device_complete_get_history (skeleton, invocation,
g_variant_builder_end (&builder));
out:
if (array != NULL)
g_ptr_array_unref (array);
if (error != NULL)
return TRUE;
}
/**
* up_device_refresh:
*
* Return %TRUE on success, %FALSE if we failed to refresh or no data
**/
static gboolean
up_device_refresh (UpExportedDevice *skeleton,
GDBusMethodInvocation *invocation,
UpDevice *device)
{
up_device_refresh_internal (device);
up_exported_device_complete_refresh (skeleton, invocation);
return TRUE;
}
static void
up_device_export_skeleton (UpDevice *device)
{
GError *error = NULL;
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (device->priv->skeleton),
up_daemon_get_dbus_connection (device->priv->daemon),
device->priv->object_path,
&error);
if (error != NULL) {
g_critical ("error registering device on system bus: %s", error->message);
g_error_free (error);
}
}
/**
* up_device_register_display_device:
**/
gboolean
up_device_register_display_device (UpDevice *device,
UpDaemon *daemon)
{
g_return_val_if_fail (UP_IS_DEVICE (device), FALSE);
device->priv->daemon = g_object_ref (daemon);
device->priv->object_path = g_build_filename (UP_DEVICES_DBUS_PATH, "DisplayDevice", NULL);
up_device_export_skeleton (device);
return TRUE;
}
@ -918,7 +639,7 @@ up_device_refresh_internal (UpDevice *device)
/* the first time, print all properties */
if (!device->priv->has_ever_refresh) {
g_debug ("added native-path: %s\n", device->priv->native_path);
g_debug ("added native-path: %s\n", up_exported_device_get_native_path (device->priv->skeleton));
device->priv->has_ever_refresh = TRUE;
goto out;
}
@ -926,23 +647,6 @@ out:
return ret;
}
/**
* up_device_refresh:
*
* Return %TRUE on success, %FALSE if we failed to refresh or no data
**/
gboolean
up_device_refresh (UpDevice *device, DBusGMethodInvocation *context)
{
gboolean ret;
g_return_val_if_fail (UP_IS_DEVICE (device), FALSE);
ret = up_device_refresh_internal (device);
dbus_g_method_return (context);
return ret;
}
/**
* up_device_get_object_path:
**/
@ -973,8 +677,8 @@ up_device_compute_object_path (UpDevice *device)
const gchar *type;
guint i;
type = up_device_kind_to_string (device->priv->type);
native_path = device->priv->native_path;
type = up_device_kind_to_string (up_exported_device_get_type_ (device->priv->skeleton));
native_path = up_exported_device_get_native_path (device->priv->skeleton);
basename = g_path_get_basename (native_path);
id = g_strjoin ("_", type, basename, NULL);
@ -1003,8 +707,8 @@ up_device_register_device (UpDevice *device)
{
device->priv->object_path = up_device_compute_object_path (device);
g_debug ("object path = %s", device->priv->object_path);
dbus_g_connection_register_g_object (device->priv->system_bus_connection,
device->priv->object_path, G_OBJECT (device));
up_device_export_skeleton (device);
return TRUE;
}
@ -1017,11 +721,11 @@ up_device_perhaps_changed_cb (GObject *object, GParamSpec *pspec, UpDevice *devi
g_return_if_fail (UP_IS_DEVICE (device));
/* save new history */
up_history_set_state (device->priv->history, device->priv->state);
up_history_set_charge_data (device->priv->history, device->priv->percentage);
up_history_set_rate_data (device->priv->history, device->priv->energy_rate);
up_history_set_time_full_data (device->priv->history, device->priv->time_to_full);
up_history_set_time_empty_data (device->priv->history, device->priv->time_to_empty);
up_history_set_state (device->priv->history, up_exported_device_get_state (device->priv->skeleton));
up_history_set_charge_data (device->priv->history, up_exported_device_get_percentage (device->priv->skeleton));
up_history_set_rate_data (device->priv->history, up_exported_device_get_energy_rate (device->priv->skeleton));
up_history_set_time_full_data (device->priv->history, up_exported_device_get_time_to_full (device->priv->skeleton));
up_history_set_time_empty_data (device->priv->history, up_exported_device_get_time_to_empty (device->priv->skeleton));
}
/**
@ -1030,17 +734,19 @@ up_device_perhaps_changed_cb (GObject *object, GParamSpec *pspec, UpDevice *devi
static void
up_device_init (UpDevice *device)
{
GError *error = NULL;
device->priv = UP_DEVICE_GET_PRIVATE (device);
device->priv->history = up_history_new ();
device->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (device->priv->system_bus_connection == NULL) {
g_error ("error getting system bus: %s", error->message);
g_error_free (error);
}
g_signal_connect (device, "notify::update-time", G_CALLBACK (up_device_perhaps_changed_cb), device);
device->priv->skeleton = up_exported_device_skeleton_new ();
g_signal_connect (device->priv->skeleton, "handle-get-history",
G_CALLBACK (up_device_get_history), device);
g_signal_connect (device->priv->skeleton, "handle-get-statistics",
G_CALLBACK (up_device_get_statistics), device);
g_signal_connect (device->priv->skeleton, "handle-refresh",
G_CALLBACK (up_device_refresh), device);
}
/**
@ -1060,14 +766,9 @@ up_device_finalize (GObject *object)
g_object_unref (device->priv->native);
if (device->priv->daemon != NULL)
g_object_unref (device->priv->daemon);
if (device->priv->props_idle_id != 0)
g_source_remove (device->priv->props_idle_id);
g_object_unref (device->priv->history);
g_object_unref (device->priv->skeleton);
g_free (device->priv->object_path);
g_free (device->priv->vendor);
g_free (device->priv->model);
g_free (device->priv->serial);
g_free (device->priv->native_path);
G_OBJECT_CLASS (up_device_parent_class)->finalize (object);
}
@ -1085,8 +786,6 @@ up_device_class_init (UpDeviceClass *klass)
g_type_class_add_private (klass, sizeof (UpDevicePrivate));
dbus_g_object_type_install_info (UP_TYPE_DEVICE, &dbus_glib_up_device_object_info);
/**
* UpDevice:update-time:
*/
@ -1336,8 +1035,6 @@ up_device_class_init (UpDeviceClass *klass)
g_param_spec_string ("icon-name",
NULL, NULL, NULL,
G_PARAM_READABLE));
dbus_g_error_domain_register (UP_DEVICE_ERROR, NULL, UP_DEVICE_TYPE_ERROR);
}
/**
@ -1348,4 +1045,3 @@ up_device_new (void)
{
return UP_DEVICE (g_object_new (UP_TYPE_DEVICE, NULL));
}

View file

@ -23,7 +23,6 @@
#define __UP_DEVICE_H__
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "up-daemon.h"
@ -58,17 +57,6 @@ typedef struct
gboolean *online);
} UpDeviceClass;
typedef enum
{
UP_DEVICE_ERROR_GENERAL,
UP_DEVICE_NUM_ERRORS
} UpDeviceError;
#define UP_DEVICE_ERROR up_device_error_quark ()
#define UP_DEVICE_TYPE_ERROR (up_device_error_get_type ())
GQuark up_device_error_quark (void);
GType up_device_error_get_type (void);
GType up_device_get_type (void);
UpDevice *up_device_new (void);
@ -87,18 +75,6 @@ gboolean up_device_get_online (UpDevice *device,
gboolean *online);
gboolean up_device_refresh_internal (UpDevice *device);
/* exported methods */
gboolean up_device_refresh (UpDevice *device,
DBusGMethodInvocation *context);
gboolean up_device_get_history (UpDevice *device,
const gchar *type,
guint timespan,
guint resolution,
DBusGMethodInvocation *context);
gboolean up_device_get_statistics (UpDevice *device,
const gchar *type,
DBusGMethodInvocation *context);
G_END_DECLS
#endif /* __UP_DEVICE_H__ */