Merge lp:~mterry/indicator-messages/tell-accounts-services into lp:indicator-messages/0.3

Proposed by Michael Terry on 2012-02-15
Status: Merged
Merged at revision: 249
Proposed branch: lp:~mterry/indicator-messages/tell-accounts-services
Merge into: lp:indicator-messages/0.3
Diff against target: 239 lines (+205/-0)
1 file modified
src/messages-service-dbus.c (+205/-0)
To merge this branch: bzr merge lp:~mterry/indicator-messages/tell-accounts-services
Reviewer Review Type Date Requested Status
Charles Kerr (community) 2012-02-15 Approve on 2012-02-15
Review via email: mp+93290@code.launchpad.net

Description of the change

Tell accounts service about whether we have messages. That way, LightDM can in turn notify unity-greeter.

To post a comment you must log in.
Charles Kerr (charlesk) wrote :

The patch is convoluted wrt stacking dbus calls, but it's probably unavoidable for this task. Except for some superficial changes like using g_clear_object(), I would probably write it about the same... :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/messages-service-dbus.c'
2--- src/messages-service-dbus.c 2011-07-21 21:25:58 +0000
3+++ src/messages-service-dbus.c 2012-02-15 20:04:18 +0000
4@@ -42,6 +42,8 @@
5 struct _MessageServiceDbusPrivate
6 {
7 GDBusConnection * connection;
8+ GCancellable * accounts_cancel;
9+ GDBusProxy * accounts_user;
10 gboolean dot;
11 gboolean hidden;
12 };
13@@ -155,9 +157,199 @@
14 }
15
16 static void
17+accounts_notify_cb (GObject *source_object, GAsyncResult *res,
18+ gpointer user_data)
19+{
20+ GError * error = NULL;
21+ GVariant * answer = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error);
22+
23+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
24+ g_error_free(error);
25+ return; /* Must exit before accessing freed memory */
26+ }
27+
28+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data);
29+
30+ if (priv->accounts_cancel != NULL) {
31+ g_object_unref(priv->accounts_cancel);
32+ priv->accounts_cancel = NULL;
33+ }
34+
35+ if (error != NULL) {
36+ g_warning("Unable to get notify accounts service of message status: %s", error->message);
37+ g_error_free(error);
38+ return;
39+ }
40+
41+ g_variant_unref (answer);
42+}
43+
44+static void
45+accounts_notify (MessageServiceDbus *self)
46+{
47+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self);
48+
49+ if (priv->accounts_user == NULL)
50+ return; /* We're not able to talk to accounts service */
51+
52+ if (priv->accounts_cancel != NULL) {
53+ /* Cancel old notify before starting new one */
54+ g_cancellable_cancel(priv->accounts_cancel);
55+ g_object_unref(priv->accounts_cancel);
56+ priv->accounts_cancel = NULL;
57+ }
58+
59+ priv->accounts_cancel = g_cancellable_new();
60+ g_dbus_proxy_call(priv->accounts_user,
61+ "SetXHasMessages",
62+ g_variant_new ("(b)", priv->dot),
63+ G_DBUS_CALL_FLAGS_NONE,
64+ -1, /* timeout */
65+ priv->accounts_cancel,
66+ accounts_notify_cb,
67+ self);
68+}
69+
70+static void
71+get_accounts_user_proxy_cb (GObject *source_object, GAsyncResult *res,
72+ gpointer user_data)
73+{
74+ GError * error = NULL;
75+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
76+
77+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
78+ g_error_free(error);
79+ return; /* Must exit before accessing freed memory */
80+ }
81+
82+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data);
83+
84+ if (priv->accounts_cancel != NULL) {
85+ g_object_unref(priv->accounts_cancel);
86+ priv->accounts_cancel = NULL;
87+ }
88+
89+ if (error != NULL) {
90+ g_warning("Unable to get proxy of accountsservice: %s", error->message);
91+ g_error_free(error);
92+ return;
93+ }
94+
95+ priv->accounts_user = proxy;
96+ accounts_notify (MESSAGE_SERVICE_DBUS (user_data));
97+}
98+
99+static void
100+get_accounts_user_find_user_cb (GObject *source_object, GAsyncResult *res,
101+ gpointer user_data)
102+{
103+ GError * error = NULL;
104+ GVariant * answer = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error);
105+
106+ /* We're done with main accounts proxy now */
107+ g_object_unref (source_object);
108+
109+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
110+ g_error_free(error);
111+ return; /* Must exit before accessing freed memory */
112+ }
113+
114+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data);
115+
116+ if (priv->accounts_cancel != NULL) {
117+ g_object_unref(priv->accounts_cancel);
118+ priv->accounts_cancel = NULL;
119+ }
120+
121+ if (error != NULL) {
122+ g_warning("Unable to get object name of user from accountsservice: %s", error->message);
123+ g_error_free(error);
124+ return;
125+ }
126+
127+ if (!g_variant_is_of_type (answer, G_VARIANT_TYPE ("(o)"))) {
128+ g_warning("Unexpected type from FindUserByName: %s", g_variant_get_type_string (answer));
129+ g_variant_unref(answer);
130+ return;
131+ }
132+
133+ const gchar *path;
134+ g_variant_get(answer, "(&o)", &path);
135+
136+ priv->accounts_cancel = g_cancellable_new();
137+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
138+ G_DBUS_PROXY_FLAGS_NONE,
139+ NULL,
140+ "org.freedesktop.Accounts",
141+ path,
142+ "org.freedesktop.Accounts.User",
143+ priv->accounts_cancel,
144+ get_accounts_user_proxy_cb,
145+ user_data);
146+
147+ g_variant_unref (answer);
148+}
149+
150+static void
151+get_accounts_proxy_cb (GObject *source_object, GAsyncResult *res,
152+ gpointer user_data)
153+{
154+ GError * error = NULL;
155+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
156+
157+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
158+ g_error_free(error);
159+ return; /* Must exit before accessing freed memory */
160+ }
161+
162+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data);
163+
164+ if (priv->accounts_cancel != NULL) {
165+ g_object_unref(priv->accounts_cancel);
166+ priv->accounts_cancel = NULL;
167+ }
168+
169+ if (error != NULL) {
170+ g_warning("Unable to get proxy of accountsservice: %s", error->message);
171+ g_error_free(error);
172+ return;
173+ }
174+
175+ priv->accounts_cancel = g_cancellable_new();
176+ g_dbus_proxy_call(proxy,
177+ "FindUserByName",
178+ g_variant_new ("(s)", g_get_user_name ()),
179+ G_DBUS_CALL_FLAGS_NONE,
180+ -1, /* timeout */
181+ priv->accounts_cancel,
182+ get_accounts_user_find_user_cb,
183+ user_data);
184+}
185+
186+static void
187+get_accounts_proxy (MessageServiceDbus *self)
188+{
189+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self);
190+
191+ g_return_if_fail(priv->accounts_cancel == NULL);
192+
193+ priv->accounts_cancel = g_cancellable_new();
194+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
195+ G_DBUS_PROXY_FLAGS_NONE,
196+ NULL,
197+ "org.freedesktop.Accounts",
198+ "/org/freedesktop/Accounts",
199+ "org.freedesktop.Accounts",
200+ priv->accounts_cancel,
201+ get_accounts_proxy_cb,
202+ self);
203+}
204+
205+static void
206 message_service_dbus_init (MessageServiceDbus *self)
207 {
208 g_bus_get(G_BUS_TYPE_SESSION, NULL, connection_cb, self);
209+ get_accounts_proxy (self);
210
211 MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self);
212
213@@ -177,6 +369,17 @@
214 priv->connection = NULL;
215 }
216
217+ if (priv->accounts_cancel != NULL) {
218+ g_cancellable_cancel(priv->accounts_cancel);
219+ g_object_unref(priv->accounts_cancel);
220+ priv->accounts_cancel = NULL;
221+ }
222+
223+ if (priv->accounts_user != NULL) {
224+ g_object_unref(priv->accounts_user);
225+ priv->accounts_user = NULL;
226+ }
227+
228 G_OBJECT_CLASS (message_service_dbus_parent_class)->dispose (object);
229 return;
230 }
231@@ -240,6 +443,8 @@
232 g_variant_new("(b)", priv->dot),
233 NULL);
234 }
235+
236+ accounts_notify (self);
237 }
238 return;
239 }

Subscribers

People subscribed via source and target branches