aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/messages-service-dbus.c205
1 files changed, 205 insertions, 0 deletions
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;
};
@@ -155,9 +157,199 @@ connection_cb (GObject * object, GAsyncResult * res, gpointer user_data)
}
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;
}