From 7c2a156d86696b8ae8793abc6913a63aa05792cb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 3 Oct 2013 15:42:50 -0500 Subject: don't create proxies for each upower device. --- src/Makefile.am | 19 - src/device-provider-upower.c | 180 ++++++--- src/org.freedesktop.UPower.Device.xml | 705 ---------------------------------- 3 files changed, 126 insertions(+), 778 deletions(-) delete mode 100644 src/org.freedesktop.UPower.Device.xml diff --git a/src/Makefile.am b/src/Makefile.am index 92117fc..be746db 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,24 +25,6 @@ BUILT_SOURCES += $(upower_dbus_sources) CLEANFILES += $(upower_dbus_sources) EXTRA_DIST += org.freedesktop.UPower.xml -### -### - -upower_device_dbus_sources = \ - dbus-upower-device.c \ - dbus-upower-device.h - -$(upower_device_dbus_sources): org.freedesktop.UPower.Device.xml - $(AM_V_GEN) gdbus-codegen \ - --c-namespace Dbus \ - --interface-prefix org.freedesktop.UPower \ - --generate-c-code dbus-upower-device \ - $^ - -BUILT_SOURCES += $(upower_device_dbus_sources) -CLEANFILES += $(upower_device_dbus_sources) -EXTRA_DIST += org.freedesktop.UPower.Device.xml - ### ### ### @@ -51,7 +33,6 @@ noinst_LIBRARIES = libindicatorpower-upower.a libindicatorpower-service.a libindicatorpower_upower_a_SOURCES = \ $(upower_dbus_sources) \ - $(upower_device_dbus_sources) \ device-provider-upower.c \ device-provider-upower.h diff --git a/src/device-provider-upower.c b/src/device-provider-upower.c index 05faeab..f890a02 100644 --- a/src/device-provider-upower.c +++ b/src/device-provider-upower.c @@ -20,7 +20,6 @@ #include "config.h" #include "dbus-upower.h" -#include "dbus-upower-device.h" #include "device.h" #include "device-provider.h" #include "device-provider-upower.h" @@ -34,6 +33,8 @@ struct _IndicatorPowerDeviceProviderUPowerPriv { + GDBusConnection * bus; + DbusUPower * upower_proxy; GHashTable * devices; /* dbus object path --> IndicatorPowerDevice */ GCancellable * cancellable; @@ -65,6 +66,12 @@ G_DEFINE_TYPE_WITH_CODE ( **** UPOWER DBUS ***/ +struct device_get_all_data +{ + char * path; + IndicatorPowerDeviceProviderUPower * self; +}; + static void emit_devices_changed (IndicatorPowerDeviceProviderUPower * self) { @@ -72,65 +79,95 @@ emit_devices_changed (IndicatorPowerDeviceProviderUPower * self) } static void -on_upower_device_proxy_ready (GObject * o, GAsyncResult * res, gpointer gself) +on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) { - GError * err; - DbusDevice * tmp; + GError * error; + GVariant * response; + struct device_get_all_data * data = gdata; - err = NULL; - tmp = dbus_device_proxy_new_for_bus_finish (res, &err); - if (err != NULL) + error = NULL; + response = g_dbus_connection_call_finish (G_DBUS_CONNECTION(o), res, &error); + if (error != NULL) { - g_warning ("Unable to get UPower Device Proxy: %s", err->message); - g_error_free (err); + if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) + g_warning ("Error acquiring bus: %s", error->message); + g_error_free (error); } else { - /* use this proxy's properties to update our own IndicatorPowerDevice */ - + guint32 kind = 0; + guint32 state = 0; + gdouble percentage = 0; + gint64 time_to_empty = 0; + gint64 time_to_full = 0; + time_t time; IndicatorPowerDevice * device; - IndicatorPowerDeviceProviderUPower * self; - priv_t * p; - - self = INDICATOR_POWER_DEVICE_PROVIDER_UPOWER (gself); - p = self->priv; - - const guint kind = dbus_device_get_type_ (tmp); - const gdouble percentage = dbus_device_get_percentage (tmp); - const guint state = dbus_device_get_state (tmp); - const gint64 time_to_empty = dbus_device_get_time_to_empty (tmp); - const gint64 time_to_full = dbus_device_get_time_to_full (tmp); - const time_t time = time_to_empty ? time_to_empty : time_to_full; - const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (tmp)); - - device = indicator_power_device_new (path, - kind, - percentage, - state, - time); - - g_hash_table_insert (p->devices, - g_strdup (path), - g_object_ref (device)); - - emit_devices_changed (self); - - g_object_unref (device); - g_object_unref (tmp); + IndicatorPowerDeviceProviderUPowerPriv * p = data->self->priv; + GVariant * dict = g_variant_get_child_value (response, 0); + + g_variant_lookup (dict, "Type", "u", &kind); + g_variant_lookup (dict, "State", "u", &state); + g_variant_lookup (dict, "Percentage", "d", &percentage); + g_variant_lookup (dict, "TimeToEmpty", "x", &time_to_empty); + g_variant_lookup (dict, "TimeToFull", "x", &time_to_full); + time = time_to_empty ? time_to_empty : time_to_full; + + if ((device = g_hash_table_lookup (p->devices, data->path))) + { + g_object_set (device, INDICATOR_POWER_DEVICE_KIND, (gint)kind, + INDICATOR_POWER_DEVICE_STATE, (gint)state, + INDICATOR_POWER_DEVICE_OBJECT_PATH, data->path, + INDICATOR_POWER_DEVICE_PERCENTAGE, percentage, + INDICATOR_POWER_DEVICE_TIME, (guint64)time, + NULL); + } + else + { + device = indicator_power_device_new (data->path, + kind, + percentage, + state, + time); + + g_hash_table_insert (p->devices, + g_strdup (data->path), + g_object_ref (device)); + + g_object_unref (device); + } + + emit_devices_changed (data->self); + g_variant_unref (dict); + g_variant_unref (response); } + + g_free (data->path); + g_slice_free (struct device_get_all_data, data); } static void update_device_from_object_path (IndicatorPowerDeviceProviderUPower * self, const char * path) { - dbus_device_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - BUS_NAME, - path, - self->priv->cancellable, - on_upower_device_proxy_ready, - self); + priv_t * p = self->priv; + struct device_get_all_data * data; + + data = g_slice_new (struct device_get_all_data); + data->path = g_strdup (path); + data->self = self; + + g_dbus_connection_call (p->bus, + BUS_NAME, + path, + "org.freedesktop.DBus.Properties", + "GetAll", + g_variant_new ("(s)", "org.freedesktop.UPower.Device"), + G_VARIANT_TYPE("(a{sv})"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, /* default timeout */ + p->cancellable, + on_device_properties_ready, + data); } /* @@ -257,7 +294,7 @@ on_upower_proxy_ready (GObject * source G_GNUC_UNUSED, DbusUPower * proxy; err = NULL; - proxy = dbus_upower_proxy_new_for_bus_finish (res, &err); + proxy = dbus_upower_proxy_new_finish (res, &err); if (err != NULL) { g_warning ("Unable to get UPower proxy: %s", err->message); @@ -286,6 +323,42 @@ on_upower_proxy_ready (GObject * source G_GNUC_UNUSED, } } +static void +on_bus_ready (GObject * source_object G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gself) +{ + GError * error; + GDBusConnection * tmp; + + error = NULL; + tmp = g_bus_get_finish (res, &error); + if (error != NULL) + { + if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) + g_warning ("Error acquiring bus: %s", error->message); + g_error_free (error); + } + else + { + IndicatorPowerDeviceProviderUPower * self; + priv_t * p; + + self = INDICATOR_POWER_DEVICE_PROVIDER_UPOWER (gself); + p = self->priv; + + p->bus = tmp; + + dbus_upower_proxy_new (p->bus, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + BUS_NAME, + BUS_PATH, + p->cancellable, + on_upower_proxy_ready, + self); + } +} + /*** **** IndicatorPowerDeviceProvider virtual functions ***/ @@ -339,6 +412,8 @@ my_dispose (GObject * o) g_hash_table_remove_all (p->devices); + g_clear_object (&p->bus); + G_OBJECT_CLASS (indicator_power_device_provider_upower_parent_class)->dispose (o); } @@ -402,13 +477,10 @@ indicator_power_device_provider_upower_init (IndicatorPowerDeviceProviderUPower g_free, NULL); - dbus_upower_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - BUS_NAME, - BUS_PATH, - p->cancellable, - on_upower_proxy_ready, - self); + g_bus_get (G_BUS_TYPE_SYSTEM, + p->cancellable, + on_bus_ready, + self); } /*** diff --git a/src/org.freedesktop.UPower.Device.xml b/src/org.freedesktop.UPower.Device.xml deleted file mode 100644 index 7c9a65b..0000000 --- a/src/org.freedesktop.UPower.Device.xml +++ /dev/null @@ -1,705 +0,0 @@ - -]> - - - - - - Objects implementing this interface are usually discovered through - the org.freedesktop.UPower interface on - the /org/freedesktop/UPower object on - the D-Bus system bus service with the well-known - name org.freedesktop.UPower using - the - EnumerateDevices - method. - - - - -$ dbus-send --print-reply \ - --system \ - --dest=org.freedesktop.UPower \ - /org/freedesktop/UPower/devices/battery_BAT0 \ - org.freedesktop.DBus.Properties.GetAll \ - string:org.freedesktop.UPower.Device - -method return sender=:1.386 -> dest=:1.477 reply_serial=2 - array [ - dict entry( - string "native-path" - variant string "/sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0" - ) - dict entry( - string "vendor" - variant string "SONY" - ) - dict entry( - string "model" - variant string "42T4568" - ) - dict entry( - string "serial" - variant string "4179" - ) - dict entry( - string "update-time" - variant uint64 1226417875 - ) - dict entry( - string "type" - variant uint 2 - ) - dict entry( - string "power-supply" - variant boolean true - ) - dict entry( - string "has-history" - variant boolean true - ) - dict entry( - string "has-statistics" - variant boolean true - ) - dict entry( - string "online" - variant boolean false - ) - dict entry( - string "energy" - variant double 72.85 - ) - dict entry( - string "energy-empty" - variant double 0 - ) - dict entry( - string "energy-full" - variant double 74.55 - ) - dict entry( - string "energy-full-design" - variant double 74.88 - ) - dict entry( - string "energy-rate" - variant double 0 - ) - dict entry( - string "voltage" - variant double 16.415 - ) - dict entry( - string "time-to-empty" - variant int64 0 - ) - dict entry( - string "time-to-full" - variant int64 0 - ) - dict entry( - string "percentage" - variant double 97.7197 - ) - dict entry( - string "is-present" - variant boolean true - ) - dict entry( - string "state" - variant uint 3 - ) - dict entry( - string "is-rechargeable" - variant boolean true - ) - dict entry( - string "capacity" - variant double 100 - ) - dict entry( - string "technology" - variant uint 1 - ) - ] - - - - - Unless otherwise noted, an empty string or the value 0 in a - property on this interface means not set. - - - - - - - - - - - - Refreshes the data collected from the power source. - - - Callers need the org.freedesktop.upower.refresh-power-source authorization - - if an error occured while refreshing - - - - - - - - - - Some value on the power source changed. - - - - - - - - - - The type of history. - Valid types are rate or charge. - - - The amount of data to return in seconds, or 0 for all. - - - - - The approximate number of points to return. - A higher resolution is more accurate, at the expense of plotting speed. - - - - - - The history data for the power device, if the device supports history. - Data is ordered from the earliest in time, to the newest data point. - Each element contains the following members: - - - time - - The time value in seconds from the gettimeofday() method. - - - - value - - The data value, for instance the rate in W or the charge in %. - - - - state - - The state of the device, for instance charging or - discharging. - - - - - - - - - Gets history for the power device that is persistent across reboots. - - - - - - - - - - The mode for the statistics. - Valid types are charging or discharging. - - - - The statistics data for the power device. - Each element contains the following members: - - - value - - The value of the percentage point, usually in seconds - - - - accuracy - - The accuracy of the prediction in percent. - - - - - - - - - Gets statistics for the power device that may be interesting - to show on a graph in the session. - - - - - - - - - - - OS specific native path of the power source. On Linux this - is the sysfs path, for - example /sys/devices/LNXSYSTM:00/device:00/PNP0C0A:00/power_supply/BAT0. Is - blank if the device is being driven by a user space - driver. - - - - - - - - - - Name of the vendor of the battery. - - - - - - - - - - Name of the model of this battery. - - - - - - - - - - Unique serial number of the battery. - - - - - - - - - - The point in time (seconds since the Epoch Jan 1, 1970 - 0:00 UTC) that data was read from the power source. - - - - - - - - - - Type of power source. - - - - 0Unknown - - - 1Line Power - - - 2Battery - - - 3Ups - - - 4Monitor - - - 5Mouse - - - 6Keyboard - - - 7Pda - - - 8Phone - - - - - - - - - - - If the power device is used to supply the system. - This would be set TRUE for laptop batteries and UPS devices, - but set FALSE for wireless mice or PDAs. - - - - - - - - - - If the power device has history. - - - - - - - - - - If the power device has statistics. - - - - - - - - - - Whether power is currently being provided through line power. - This property is only valid if the property - type - has the value "line-power". - - - - - - - - - - Amount of energy (measured in Wh) currently available in - the power source. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - Amount of energy (measured in Wh) in the power source when - it's considered to be empty. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - Amount of energy (measured in Wh) in the power source when - it's considered full. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - Amount of energy (measured in Wh) the power source is - designed to hold when it's considered full. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - Amount of energy being drained from the source, measured - in W. If positive, the source is being discharged, if - negative it's being charged. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - Voltage in the Cell or being recorded by the meter. - - - - - - - - - - Number of seconds until the power source is considered empty. - Is set to 0 if unknown. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - Number of seconds until the power source is considered full. - Is set to 0 if unknown. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - The amount of energy left in the power source expressed as - a percentage between 0 and 100. Typically this is the same as - (energy - - energy-empty) / - (energy-full - - energy-empty). - However, some primitive power sources are capable of only - reporting percentages and in this case the energy-* - properties will be unset while this property is set. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - If the power source is present in the bay. - This field is required as some batteries are hot-removable, for example - expensive UPS and most laptop batteries. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - The battery power state. - - - - 0Unknown - - - 1Charging - - - 2Discharging - - - 3Empty - - - 4Fully charged - - - 5Pending charge - - - 6Pending discharge - - - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - If the power source is rechargeable. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - The capacity of the power source expressed as a percentage between 0 and 100. - The capacity of the battery will reduce with age. - A capacity value less than 75% is usually a sign that you should renew your battery. - Typically this value is the same as - (full-design / - full) * 100. - However, some primitive power sources are not capable reporting capacity - and in this case the capacity property will be unset. - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - Technology used in the battery: - - - - 0Unknown - - - 1Lithium ion - - - 2Lithium polymer - - - 3Lithium iron phosphate - - - 4Lead acid - - - 5Nickel cadmium - - - 6Nickel metal hydride - - - - This property is only valid if the property - type - has the value "battery". - - - - - - - - - - If the device may have been recalled by the vendor due to a suspected - fault. - This key does not imply the device is faulty, only that it approximatly - matches the description from the vendor of units that were recalled. - - - - - - - - - - The vendor that is handling the hardware recall. - - - This property is only valid if the property recall-notice is true. - - - - - - - - - - The URL to visit about the hardware recall. - - - This property is only valid if the property recall-notice is true. - - - - - - - - -- cgit v1.2.3 From adfd4c6bcdba7560635e9f57e5be00651073955a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 3 Nov 2013 17:47:10 -0600 Subject: in on_device_properties_ready(), use g_error_matches --- src/device-provider-upower.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device-provider-upower.c b/src/device-provider-upower.c index f890a02..4014853 100644 --- a/src/device-provider-upower.c +++ b/src/device-provider-upower.c @@ -89,7 +89,7 @@ on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) response = g_dbus_connection_call_finish (G_DBUS_CONNECTION(o), res, &error); if (error != NULL) { - if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Error acquiring bus: %s", error->message); g_error_free (error); } -- cgit v1.2.3 From 65fa65fbf7f66d3d3d4b0ccb0619cc8ec00c5497 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 3 Nov 2013 17:57:10 -0600 Subject: in on_device_properties_ready(), improve the g_warning() text to be more useful. --- src/device-provider-upower.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/device-provider-upower.c b/src/device-provider-upower.c index 4014853..cc4adf5 100644 --- a/src/device-provider-upower.c +++ b/src/device-provider-upower.c @@ -90,7 +90,9 @@ on_device_properties_ready (GObject * o, GAsyncResult * res, gpointer gdata) if (error != NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("Error acquiring bus: %s", error->message); + g_warning ("Error getting properties for UPower device '%s': %s", + data->path, error->message); + g_error_free (error); } else -- cgit v1.2.3 From 7dd7640162800c43f7e826d9e1dbefe4e0f9a734 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 3 Nov 2013 17:59:28 -0600 Subject: in on_bus_ready(), use g_error_matches(). --- src/device-provider-upower.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device-provider-upower.c b/src/device-provider-upower.c index cc4adf5..ad5bc98 100644 --- a/src/device-provider-upower.c +++ b/src/device-provider-upower.c @@ -337,7 +337,7 @@ on_bus_ready (GObject * source_object G_GNUC_UNUSED, tmp = g_bus_get_finish (res, &error); if (error != NULL) { - if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Error acquiring bus: %s", error->message); g_error_free (error); } -- cgit v1.2.3