From 6f2871a3050d845ea91b2f7ba360298e84515b32 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Fri, 9 Aug 2013 16:39:10 -0300 Subject: [PATCH] ecore: add upower system module. It's always enabled as it's a dbus module and links to nothing, actually the daemon doesn't need to be running -- in that case it will do nothing. In the case the daemon becomes active then it will get the OnLowBattery property and keep it in sync. NOTE: I couldn't test the property change as my laptop takes many hours to get to that situation... let's hope it works :-) --- src/Makefile_Ecore.am | 19 ++ .../ecore/system/upower/ecore_system_upower.c | 225 ++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 src/modules/ecore/system/upower/ecore_system_upower.c diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am index 5e6515ba56..c1fbf6b376 100644 --- a/src/Makefile_Ecore.am +++ b/src/Makefile_Ecore.am @@ -86,6 +86,25 @@ modules_ecore_system_systemd_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ modules_ecore_system_systemd_module_la_LIBTOOLFLAGS = --tag=disable-static endif +# upower + +ecoreupowerpkgdir = $(libdir)/ecore/system/upower/$(MODULE_ARCH) +ecoreupowerpkg_LTLIBRARIES = modules/ecore/system/upower/module.la +modules_ecore_system_upower_module_la_SOURCES = \ +modules/ecore/system/upower/ecore_system_upower.c +modules_ecore_system_upower_module_la_CPPFLAGS = \ +-I$(top_builddir)/src/lib/efl \ +@ECORE_CFLAGS@ \ +@ELDBUS_CFLAGS@ +modules_ecore_system_upower_module_la_LIBADD = \ +@USE_ECORE_LIBS@ \ +@USE_ELDBUS_LIBS@ +modules_ecore_system_upower_module_la_DEPENDENCIES = \ +@USE_ECORE_INTERNAL_LIBS@ \ +@USE_ELDBUS_INTERNAL_LIBS@ +modules_ecore_system_upower_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ +modules_ecore_system_upower_module_la_LIBTOOLFLAGS = --tag=disable-static + ### Unit tests diff --git a/src/modules/ecore/system/upower/ecore_system_upower.c b/src/modules/ecore/system/upower/ecore_system_upower.c new file mode 100644 index 0000000000..d89c4b91e8 --- /dev/null +++ b/src/modules/ecore/system/upower/ecore_system_upower.c @@ -0,0 +1,225 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +static int _log_dom = -1; +static Eldbus_Connection *_conn = NULL; + +static Eldbus_Object *_obj = NULL; +static Eldbus_Proxy *_proxy = NULL; + +#ifdef CRITICAL +#undef CRITICAL +#endif +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__) + +#ifdef ERR +#undef ERR +#endif +#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__) + +#ifdef WRN +#undef WRN +#endif +#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__) + +#ifdef DBG +#undef DBG +#endif +#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__) + +static void +_on_low_battery_from_variant(Eldbus_Message_Iter *variant) +{ + Eina_Bool val; + + if (!eldbus_message_iter_get_and_next(variant, 'b', &val)) + { + ERR("Error getting OnLowBattery."); + return; + } + + DBG("OnLowBattery=%hhu", val); + ecore_low_battery_set(val); +} + +static void +_on_low_battery_get_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, + Eldbus_Pending *pending EINA_UNUSED) +{ + Eldbus_Message_Iter *variant; + const char *errname, *errmsg; + + if (eldbus_message_error_get(msg, &errname, &errmsg)) + { + ERR("Message error %s - %s", errname, errmsg); + return; + } + if (!eldbus_message_arguments_get(msg, "v", &variant)) + { + ERR("Error getting arguments."); + return; + } + + _on_low_battery_from_variant(variant); +} + +static void +_on_low_battery_get(Eldbus_Proxy *proxy) +{ + eldbus_proxy_property_get(proxy, "OnLowBattery", + _on_low_battery_get_cb, NULL); +} + +static void +_props_changed(void *data, const Eldbus_Message *msg) +{ + Eldbus_Proxy *proxy = data; + Eldbus_Message_Iter *changed, *entry, *invalidated; + const char *iface, *prop; + + if (!eldbus_message_arguments_get(msg, "sa{sv}as", + &iface, &changed, &invalidated)) + { + ERR("Error getting data from properties changed signal."); + return; + } + + while (eldbus_message_iter_get_and_next(changed, 'e', &entry)) + { + const void *key; + Eldbus_Message_Iter *var; + if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &var)) + continue; + printf("changed on low battery\n"); + if (strcmp(key, "OnLowBattery") == 0) + { + _on_low_battery_from_variant(var); + return; + } + } + + while (eldbus_message_iter_get_and_next(invalidated, 's', &prop)) + { + printf("invalidated on low battery\n"); + if (strcmp(prop, "OnLowBattery") == 0) + { + _on_low_battery_get(proxy); + return; + } + } +} + +static void _upower_name_owner_cb(void *data, + const char *bus EINA_UNUSED, + const char *old_id, + const char *new_id) +{ + Eldbus_Proxy *proxy = data; + + DBG("org.freedesktop.UPower name owner changed from '%s' to '%s'", + old_id, new_id); + + if ((new_id) && (new_id[0])) + _on_low_battery_get(proxy); +} + +static void _ecore_system_upower_shutdown(void); + +static Eina_Bool +_ecore_system_upower_init(void) +{ + Eldbus_Signal_Handler *s; + + eldbus_init(); + + _log_dom = eina_log_domain_register("ecore_system_upower", NULL); + if (_log_dom < 0) + { + EINA_LOG_ERR("Could not register log domain: ecore_system_upower"); + goto error; + } + + _conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM); + + _obj = eldbus_object_get(_conn, "org.freedesktop.UPower", + "/org/freedesktop/UPower"); + if (!_obj) + { + ERR("could not get object name=org.freedesktop.UPower, " + "path=/org/freedesktop/UPower"); + goto error; + } + + _proxy = eldbus_proxy_get(_obj, "org.freedesktop.UPower"); + if (!_proxy) + { + ERR("could not get proxy interface=org.freedesktop.UPower, " + "name=org.freedesktop.UPower, path=/org/freedesktop/UPower"); + goto error; + } + + s = eldbus_proxy_properties_changed_callback_add(_proxy, _props_changed, + _proxy); + if (!s) + { + ERR("could not add signal handler for properties changed for proxy " + "interface=org.freedesktop.UPower, name=org.freedesktop.UPower, " + "path=/org/freedesktop/UPower"); + goto error; + } + + eldbus_name_owner_changed_callback_add(_conn, "org.freedesktop.UPower", + _upower_name_owner_cb, + _proxy, EINA_TRUE); + + DBG("ecore system 'upower' loaded"); + return EINA_TRUE; + + error: + _ecore_system_upower_shutdown(); + return EINA_FALSE; +} + +static void +_ecore_system_upower_shutdown(void) +{ + DBG("ecore system 'upower' unloaded"); + + eldbus_name_owner_changed_callback_del(_conn, "org.freedesktop.UPower", + _upower_name_owner_cb, + NULL); + + if (_proxy) + { + eldbus_proxy_unref(_proxy); + _proxy = NULL; + } + + if (_obj) + { + eldbus_object_unref(_obj); + _obj = NULL; + } + + if (_conn) + { + eldbus_connection_unref(_conn); + _conn = NULL; + } + + if (_log_dom > 0) + { + eina_log_domain_unregister(_log_dom); + _log_dom = -1; + } + + eldbus_shutdown(); +} + +EINA_MODULE_INIT(_ecore_system_upower_init); +EINA_MODULE_SHUTDOWN(_ecore_system_upower_shutdown);