From 2241a4e507bfe4328198108904dfee2cf14695e8 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Wed, 15 Feb 2012 14:56:21 -0500 Subject: tell accounts service about message status --- src/messages-service-dbus.c | 205 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) diff --git a/src/messages-service-dbus.c b/src/messages-service-dbus.c index 1585ac0..2b72f2e 100644 --- a/src/messages-service-dbus.c +++ b/src/messages-service-dbus.c @@ -42,6 +42,8 @@ typedef struct _MessageServiceDbusPrivate MessageServiceDbusPrivate; struct _MessageServiceDbusPrivate { GDBusConnection * connection; + GCancellable * accounts_cancel; + GDBusProxy * accounts_user; gboolean dot; gboolean hidden; }; @@ -154,10 +156,200 @@ connection_cb (GObject * object, GAsyncResult * res, gpointer user_data) return; } +static void +accounts_notify_cb (GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GError * error = NULL; + GVariant * answer = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error); + + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free(error); + return; /* Must exit before accessing freed memory */ + } + + MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); + + if (priv->accounts_cancel != NULL) { + g_object_unref(priv->accounts_cancel); + priv->accounts_cancel = NULL; + } + + if (error != NULL) { + g_warning("Unable to get notify accounts service of message status: %s", error->message); + g_error_free(error); + return; + } + + g_variant_unref (answer); +} + +static void +accounts_notify (MessageServiceDbus *self) +{ + MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self); + + if (priv->accounts_user == NULL) + return; /* We're not able to talk to accounts service */ + + if (priv->accounts_cancel != NULL) { + /* Cancel old notify before starting new one */ + g_cancellable_cancel(priv->accounts_cancel); + g_object_unref(priv->accounts_cancel); + priv->accounts_cancel = NULL; + } + + priv->accounts_cancel = g_cancellable_new(); + g_dbus_proxy_call(priv->accounts_user, + "SetXHasMessages", + g_variant_new ("(b)", priv->dot), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + priv->accounts_cancel, + accounts_notify_cb, + self); +} + +static void +get_accounts_user_proxy_cb (GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GError * error = NULL; + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free(error); + return; /* Must exit before accessing freed memory */ + } + + MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); + + if (priv->accounts_cancel != NULL) { + g_object_unref(priv->accounts_cancel); + priv->accounts_cancel = NULL; + } + + if (error != NULL) { + g_warning("Unable to get proxy of accountsservice: %s", error->message); + g_error_free(error); + return; + } + + priv->accounts_user = proxy; + accounts_notify (MESSAGE_SERVICE_DBUS (user_data)); +} + +static void +get_accounts_user_find_user_cb (GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GError * error = NULL; + GVariant * answer = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error); + + /* We're done with main accounts proxy now */ + g_object_unref (source_object); + + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free(error); + return; /* Must exit before accessing freed memory */ + } + + MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); + + if (priv->accounts_cancel != NULL) { + g_object_unref(priv->accounts_cancel); + priv->accounts_cancel = NULL; + } + + if (error != NULL) { + g_warning("Unable to get object name of user from accountsservice: %s", error->message); + g_error_free(error); + return; + } + + if (!g_variant_is_of_type (answer, G_VARIANT_TYPE ("(o)"))) { + g_warning("Unexpected type from FindUserByName: %s", g_variant_get_type_string (answer)); + g_variant_unref(answer); + return; + } + + const gchar *path; + g_variant_get(answer, "(&o)", &path); + + priv->accounts_cancel = g_cancellable_new(); + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.Accounts", + path, + "org.freedesktop.Accounts.User", + priv->accounts_cancel, + get_accounts_user_proxy_cb, + user_data); + + g_variant_unref (answer); +} + +static void +get_accounts_proxy_cb (GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GError * error = NULL; + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free(error); + return; /* Must exit before accessing freed memory */ + } + + MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); + + if (priv->accounts_cancel != NULL) { + g_object_unref(priv->accounts_cancel); + priv->accounts_cancel = NULL; + } + + if (error != NULL) { + g_warning("Unable to get proxy of accountsservice: %s", error->message); + g_error_free(error); + return; + } + + priv->accounts_cancel = g_cancellable_new(); + g_dbus_proxy_call(proxy, + "FindUserByName", + g_variant_new ("(s)", g_get_user_name ()), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + priv->accounts_cancel, + get_accounts_user_find_user_cb, + user_data); +} + +static void +get_accounts_proxy (MessageServiceDbus *self) +{ + MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self); + + g_return_if_fail(priv->accounts_cancel == NULL); + + priv->accounts_cancel = g_cancellable_new(); + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + "org.freedesktop.Accounts", + priv->accounts_cancel, + get_accounts_proxy_cb, + self); +} + static void message_service_dbus_init (MessageServiceDbus *self) { g_bus_get(G_BUS_TYPE_SESSION, NULL, connection_cb, self); + get_accounts_proxy (self); MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self); @@ -177,6 +369,17 @@ message_service_dbus_dispose (GObject *object) priv->connection = NULL; } + if (priv->accounts_cancel != NULL) { + g_cancellable_cancel(priv->accounts_cancel); + g_object_unref(priv->accounts_cancel); + priv->accounts_cancel = NULL; + } + + if (priv->accounts_user != NULL) { + g_object_unref(priv->accounts_user); + priv->accounts_user = NULL; + } + G_OBJECT_CLASS (message_service_dbus_parent_class)->dispose (object); return; } @@ -240,6 +443,8 @@ message_service_dbus_set_attention (MessageServiceDbus * self, gboolean attentio g_variant_new("(b)", priv->dot), NULL); } + + accounts_notify (self); } return; } -- cgit v1.2.3 From c83536fa740c42f95a01c2a92b3f49dd4d6d800c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 21 Feb 2012 09:47:19 -0600 Subject: trivial: remove unnecessary cast --- src/status-items.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/status-items.c b/src/status-items.c index 25a7aa2..8a38dda 100644 --- a/src/status-items.c +++ b/src/status-items.c @@ -253,7 +253,7 @@ module_destroy_in_idle (gpointer data) static gboolean load_status_provider (gpointer dir) { - gchar * provider = (gchar *)dir; + gchar * provider = dir; if (!g_file_test(provider, G_FILE_TEST_EXISTS)) { goto exit_final; -- cgit v1.2.3 From 9e47cefaed786f2161b9def9ecd8c8f4ac2f537a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 21 Feb 2012 09:47:42 -0600 Subject: trivial: fix comment typo --- src/status-items.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/status-items.c b/src/status-items.c index 8a38dda..f80de1c 100644 --- a/src/status-items.c +++ b/src/status-items.c @@ -294,7 +294,7 @@ load_status_provider (gpointer dir) /* Attach the module object to the status provider so that when the status provider is free'd the module - is close automatically. */ + is closed automatically. */ g_object_set_data_full(G_OBJECT(sprovider), "status-provider-module", module, module_destroy_in_idle); status_providers = g_list_prepend(status_providers, sprovider); -- cgit v1.2.3 From 5d2abcf7e0e913775c2dd2a3d7817cede0791460 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 21 Feb 2012 09:51:45 -0600 Subject: trivial: fix error message grammar --- src/status-items.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/status-items.c b/src/status-items.c index f80de1c..60533ce 100644 --- a/src/status-items.c +++ b/src/status-items.c @@ -265,7 +265,7 @@ load_status_provider (gpointer dir) module = g_module_open(provider, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); if (module == NULL) { - g_warning("Unable to module for: %s", provider); + g_warning("Unable to open module: %s", provider); goto exit_module_fail; } -- cgit v1.2.3 From 0961069f7ea384123173e99c06f3aae50b0eaa79 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 21 Feb 2012 10:05:08 -0600 Subject: trivial: fix a comment typo --- src/status-items.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/status-items.c b/src/status-items.c index 60533ce..524e1c4 100644 --- a/src/status-items.c +++ b/src/status-items.c @@ -299,8 +299,7 @@ load_status_provider (gpointer dir) status_providers = g_list_prepend(status_providers, sprovider); - /* Force and update every time just so we know we're - in a consistent state*/ + /* Force an update to ensure a consistent state*/ update_status(); goto exit_final; -- cgit v1.2.3 From b3a47ea65fb92a464aa4aa4ae3b1935e923a7986 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 21 Feb 2012 10:27:27 -0600 Subject: silence LP Bug #937438 - Coverity got confused by goto's and gave Coverity PW.BRANCH_PAST_INITIALIZATION - CID 10663 --- src/status-items.c | 97 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/src/status-items.c b/src/status-items.c index 524e1c4..70a2ad9 100644 --- a/src/status-items.c +++ b/src/status-items.c @@ -255,59 +255,64 @@ load_status_provider (gpointer dir) { gchar * provider = dir; - if (!g_file_test(provider, G_FILE_TEST_EXISTS)) { - goto exit_final; - } - - g_debug("Loading status provider: %s", provider); - - GModule * module; - - module = g_module_open(provider, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); - if (module == NULL) { - g_warning("Unable to open module: %s", provider); - goto exit_module_fail; + /* load the module */ + GModule * module = NULL; + if (g_file_test(provider, G_FILE_TEST_EXISTS)) { + g_debug("Loading status provider: %s", provider); + module = g_module_open(provider, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + if (module == NULL) { + g_warning("Unable to open module: %s", provider); + } } - /* Got it */ - GType (*type_func) (void); - if (!g_module_symbol(module, STATUS_PROVIDER_EXPORT_S, (gpointer *)&type_func)) { - g_warning("Unable to find type symbol in: %s", provider); - goto exit_module_fail; + /* find the status provider's GType */ + GType provider_type = 0; + if (module != NULL) { + GType (*type_func) (void); + if (!g_module_symbol(module, STATUS_PROVIDER_EXPORT_S, (gpointer *)&type_func)) { + g_warning("Unable to find type symbol in: %s", provider); + } else { + provider_type = type_func(); + if (provider_type == 0) { + g_warning("Unable to create type from: %s", provider); + } + } } - GType provider_type = type_func(); - if (provider_type == 0) { - g_warning("Unable to create type from: %s", provider); - goto exit_module_fail; + /* instantiate the status provider */ + StatusProvider * sprovider = NULL; + if (provider_type != 0) { + sprovider = STATUS_PROVIDER(g_object_new(provider_type, NULL)); + if (sprovider == NULL) { + g_warning("Unable to build provider from: %s", provider); + } } - StatusProvider * sprovider = STATUS_PROVIDER(g_object_new(provider_type, NULL)); - if (sprovider == NULL) { - g_warning("Unable to build provider from: %s", provider); - goto exit_module_fail; + /* use the provider */ + if (sprovider != NULL) { + /* On update let's talk to all of them and create the aggregate + value to export */ + g_signal_connect(G_OBJECT(sprovider), + STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, + G_CALLBACK(update_status), NULL); + + /* Attach the module object to the status provider so + that when the status provider is free'd the module + is closed automatically. */ + g_object_set_data_full(G_OBJECT(sprovider), + "status-provider-module", + module, module_destroy_in_idle); + module = NULL; /* don't close module in this func */ + + status_providers = g_list_prepend(status_providers, sprovider); + + /* Force an update to ensure a consistent state */ + update_status(); } - /* On update let's talk to all of them and create the aggregate - value to export */ - g_signal_connect(G_OBJECT(sprovider), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, G_CALLBACK(update_status), NULL); - - /* Attach the module object to the status provider so - that when the status provider is free'd the module - is closed automatically. */ - g_object_set_data_full(G_OBJECT(sprovider), "status-provider-module", module, module_destroy_in_idle); - - status_providers = g_list_prepend(status_providers, sprovider); - - /* Force an update to ensure a consistent state*/ - update_status(); - - goto exit_final; - -exit_module_fail: - g_module_close(module); - -exit_final: + /* cleanup */ + if (module != NULL) + g_module_close(module); g_free(provider); - return FALSE; + return FALSE; /* only call this idle func once */ } -- cgit v1.2.3 From 3e6ea0a46c929ac0a4072915058508316510fabd Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 22 Feb 2012 23:55:23 -0600 Subject: 0.5.92 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 7fb043a..179d679 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ AC_INIT(src/indicator-messages.c) AC_PREREQ(2.53) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(indicator-messages, 0.5.91) +AM_INIT_AUTOMAKE(indicator-messages, 0.5.92) AM_MAINTAINER_MODE -- cgit v1.2.3