~ubuntu-desktop/indicator-me/ubuntu

« back to all changes in this revision

Viewing changes to src/me-service-gwibber.c

  • Committer: Sebastien Bacher
  • Date: 2010-03-24 12:59:43 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: seb128@ubuntu.com-20100324125943-e54i1nihe8h3wb2i
Tags: 0.2.6-0ubuntu1
releasing version 0.2.6-0ubuntu1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 
3
 
Logic to send messages via gwibber
 
3
GObject wrapper for the gwibber service
4
4
 
5
5
Copyright 2010 Canonical Ltd.
6
6
 
20
20
with this program.  If not, see <http://www.gnu.org/licenses/>.
21
21
*/
22
22
 
 
23
#include "me-service-gwibber.h"
 
24
 
23
25
#include <glib.h>
 
26
 
24
27
#include <dbus/dbus-glib.h>
25
 
 
26
 
#define GWIBBER_ADDRESS    "com.Gwibber.Service"
27
 
#define GWIBBER_OBJECT     "/com/gwibber/Service"
28
 
#define GWIBBER_INTERFACE  "com.Gwibber.Service"
29
 
 
30
 
static DBusGProxy * gwibber_proxy = NULL;
31
 
 
32
 
/*
33
 
  static */ void
34
 
gwibber_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
35
 
{
36
 
        g_debug ("gwibber_send_response");
37
 
 
38
 
        return;
39
 
}
40
 
 
41
 
static void
42
 
setup_gwibber_proxy (void) {
43
 
        DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
44
 
        g_return_if_fail(bus != NULL);
45
 
 
46
 
        if (gwibber_proxy == NULL) {
47
 
                gwibber_proxy = dbus_g_proxy_new_for_name(bus,
48
 
                                                                                                  GWIBBER_ADDRESS,
49
 
                                                                                                  GWIBBER_OBJECT,
50
 
                                                                                                  GWIBBER_INTERFACE);
51
 
        }
52
 
        g_return_if_fail (gwibber_proxy != NULL);
 
28
#include <dbus/dbus-glib-bindings.h>
 
29
 
 
30
#define DBUS_SERVICE_ADDRESS            "com.Gwibber.Service"
 
31
#define DBUS_SERVICE_SERVICE_OBJECT     "/com/gwibber/Service"
 
32
#define DBUS_SERVICE_SERVICE_INTERFACE  "com.Gwibber.Service"
 
33
 
 
34
#define DBUS_SERVICE_ACCOUNTS_OBJECT    "/com/gwibber/Accounts"
 
35
#define DBUS_SERVICE_ACCOUNTS_INTERFACE "com.Gwibber.Accounts"
 
36
 
 
37
/* gobject infrastructure */
 
38
 
 
39
typedef struct _GwibberServicePrivate GwibberServicePrivate;
 
40
struct _GwibberServicePrivate {
 
41
        DBusGProxy * dbus_proxy;
 
42
        DBusGProxy * service_proxy;
 
43
        DBusGProxy * accounts_proxy;
 
44
        int status;
 
45
        gboolean has_configured_accounts;
 
46
};
 
47
 
 
48
/* Signals */
 
49
enum {
 
50
        STATUS_CHANGED,
 
51
        LAST_SIGNAL
 
52
};
 
53
 
 
54
static guint signals[LAST_SIGNAL] = { 0 };
 
55
 
 
56
/* Prototypes */
 
57
static void gwibber_service_class_init (GwibberServiceClass *klass);
 
58
static void gwibber_service_init       (GwibberService *self);
 
59
static void gwibber_service_dispose    (GObject *object);
 
60
static void gwibber_service_finalize   (GObject *object);
 
61
 
 
62
static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, GwibberService * self);
 
63
static void gwibber_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata);
 
64
static void setup_service_proxies (GwibberService *self);
 
65
static void query_account_manager (GwibberService *self);
 
66
 
 
67
G_DEFINE_TYPE (GwibberService, gwibber_service, G_TYPE_OBJECT);
 
68
 
 
69
#define GWIBBER_SERVICE_GET_PRIVATE(o) \
 
70
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GWIBBER_SERVICE_TYPE, GwibberServicePrivate))
 
71
 
 
72
static void
 
73
gwibber_service_class_init (GwibberServiceClass *klass)
 
74
{
 
75
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
76
 
 
77
        g_type_class_add_private (klass, sizeof (GwibberServicePrivate));
 
78
 
 
79
        object_class->dispose = gwibber_service_dispose;
 
80
        object_class->finalize = gwibber_service_finalize;
 
81
 
 
82
        signals[STATUS_CHANGED]  = g_signal_new(GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED,
 
83
                                                                                        G_TYPE_FROM_CLASS(klass),
 
84
                                                                                        G_SIGNAL_RUN_LAST,
 
85
                                                                                        G_STRUCT_OFFSET(GwibberServiceClass, status_changed),
 
86
                                                                                        NULL, NULL,
 
87
                                                                                        g_cclosure_marshal_VOID__UINT,
 
88
                                                                                        G_TYPE_NONE, 1, G_TYPE_UINT);
 
89
        return;
 
90
}
 
91
 
 
92
static void
 
93
gwibber_service_init (GwibberService *self)
 
94
{
 
95
        GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
 
96
 
 
97
        priv->dbus_proxy = NULL;
 
98
        priv->service_proxy = NULL;
 
99
        priv->accounts_proxy = NULL;
 
100
        priv->status = GWIBBER_SERVICE_STATUS_NOT_RUNNING;
 
101
        priv->has_configured_accounts = FALSE;
 
102
 
 
103
        DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
 
104
        g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
 
105
                                          all non-DBus stuff should be done */
 
106
 
 
107
        GError * error = NULL;
 
108
 
 
109
        /* Set up the dbus Proxy */
 
110
        priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus,
 
111
                                                            DBUS_SERVICE_DBUS,
 
112
                                                            DBUS_PATH_DBUS,
 
113
                                                            DBUS_INTERFACE_DBUS,
 
114
                                                            &error);
 
115
        if (error != NULL) {
 
116
                g_warning("Unable to connect to DBus events: %s", error->message);
 
117
                g_error_free(error);
 
118
                return;
 
119
        }
 
120
 
 
121
        /* Configure the name owner changing */
 
122
        dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged",
 
123
                                G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
 
124
                                                        G_TYPE_INVALID);
 
125
        dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged",
 
126
                                G_CALLBACK(dbus_namechange),
 
127
                                self, NULL);
 
128
 
 
129
        org_freedesktop_DBus_name_has_owner_async(priv->dbus_proxy, DBUS_SERVICE_ADDRESS, gwibber_exists_cb, self);
 
130
 
 
131
        return;
 
132
}
 
133
 
 
134
static void
 
135
gwibber_service_dispose (GObject *object)
 
136
{
 
137
        GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(object);
 
138
 
 
139
        if (priv->dbus_proxy != NULL) {
 
140
                g_object_unref(priv->dbus_proxy);
 
141
                priv->dbus_proxy = NULL;
 
142
        }
 
143
 
 
144
        if (priv->service_proxy != NULL) {
 
145
                g_object_unref(priv->service_proxy);
 
146
                priv->service_proxy = NULL;
 
147
        }
 
148
 
 
149
        if (priv->accounts_proxy != NULL) {
 
150
                g_object_unref(priv->accounts_proxy);
 
151
                priv->accounts_proxy = NULL;
 
152
        }
 
153
 
 
154
        G_OBJECT_CLASS (gwibber_service_parent_class)->dispose (object);
 
155
        return;
 
156
}
 
157
 
 
158
static void
 
159
gwibber_service_finalize (GObject *object)
 
160
{
 
161
        G_OBJECT_CLASS (gwibber_service_parent_class)->finalize (object);
 
162
        return;
 
163
}
 
164
 
 
165
 
 
166
/* Watch for Gwibber coming on and off the bus. */
 
167
static void
 
168
dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, GwibberService * self)
 
169
{
 
170
        g_return_if_fail (IS_GWIBBER_SERVICE (self));
 
171
 
 
172
        GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
 
173
 
 
174
        if (prev[0] == '\0' && g_strcmp0(name, DBUS_SERVICE_ADDRESS) == 0) {
 
175
                g_debug("Gwibber Service coming online");
 
176
                priv->status = GWIBBER_SERVICE_STATUS_RUNNING;
 
177
                if (priv->service_proxy == NULL ||
 
178
                        priv->accounts_proxy == NULL)
 
179
                        setup_service_proxies (self);
 
180
                query_account_manager (self);
 
181
        }
 
182
 
 
183
        if (new[0] == '\0' && g_strcmp0(name, DBUS_SERVICE_ADDRESS) == 0) {
 
184
                g_debug("Gwibber Service going offline");
 
185
                priv->status = GWIBBER_SERVICE_STATUS_NOT_RUNNING;
 
186
                g_signal_emit (G_OBJECT (self), GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE);
 
187
                if (priv->service_proxy != NULL) {
 
188
                        g_object_unref(priv->service_proxy);
 
189
                        priv->service_proxy = NULL;
 
190
                }
 
191
                if (priv->accounts_proxy != NULL) {
 
192
                        g_object_unref(priv->accounts_proxy);
 
193
                        priv->accounts_proxy = NULL;
 
194
                }
 
195
        }
 
196
 
 
197
        return;
 
198
}
 
199
 
 
200
static void
 
201
get_accounts_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
 
202
{
 
203
        GError *error = NULL;
 
204
        gchar  *accounts_string = NULL;
 
205
 
 
206
        dbus_g_proxy_end_call (proxy, call, &error,
 
207
                                                   G_TYPE_STRING, &accounts_string,
 
208
                                                   G_TYPE_INVALID);
 
209
 
 
210
        if (error != NULL) {
 
211
                g_warning ("GetAccounts: %s", error->message);
 
212
                g_error_free (error);
 
213
                g_free (accounts_string);
 
214
                return;
 
215
        }
 
216
 
 
217
        /* don't print the accounts string, it contains passwords */
 
218
        /* g_debug ("GetAccounts: %s", accounts_string); */
 
219
 
 
220
        g_return_if_fail (IS_GWIBBER_SERVICE (data));
 
221
        GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(data);
 
222
        g_return_if_fail (priv != NULL);
 
223
        /* Note: not free'ing accounts_string here, but g_return_if_fail are
 
224
           meant to catch design errors, not runtime ones */
 
225
 
 
226
        priv->status = GWIBBER_SERVICE_STATUS_RUNNING;
 
227
        priv->has_configured_accounts = g_strrstr (accounts_string, " \"send_enabled\": true,") ? TRUE : FALSE;
 
228
 
 
229
        /* trigger a status update */
 
230
        g_signal_emit (G_OBJECT (data),
 
231
                                   GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID,
 
232
                                   0, priv->status, TRUE);
 
233
 
 
234
        g_free (accounts_string);
 
235
 
 
236
        return;
 
237
}
 
238
 
 
239
static void
 
240
query_account_manager (GwibberService *self)
 
241
{
 
242
        g_return_if_fail (IS_GWIBBER_SERVICE (self));
 
243
 
 
244
        GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
 
245
 
 
246
        if (priv->service_proxy == NULL) {
 
247
                g_warning ("no service_proxy, can't query for accounts");
 
248
                return;
 
249
        }
 
250
 
 
251
        dbus_g_proxy_begin_call(priv->service_proxy,
 
252
                                "GetAccounts",
 
253
                                get_accounts_response,
 
254
                                self,
 
255
                                NULL,
 
256
                                                        G_TYPE_INVALID);
 
257
}
 
258
 
 
259
static void
 
260
accounts_changed (DBusGProxy *proxy, const gchar *id, GwibberService *self)
 
261
{
 
262
        g_return_if_fail (IS_GWIBBER_SERVICE (self));
 
263
 
 
264
        g_debug ("accounts_changed");
 
265
 
 
266
        query_account_manager (self);
 
267
 
 
268
        return;
 
269
}
 
270
 
 
271
static void
 
272
setup_service_proxies (GwibberService *self)
 
273
{
 
274
        g_return_if_fail (IS_GWIBBER_SERVICE (self));
 
275
 
 
276
        GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
 
277
 
 
278
        DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
 
279
        g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
 
280
                                          all non-DBus stuff should be done */
 
281
 
 
282
        if (priv->service_proxy == NULL) {
 
283
                priv->service_proxy = dbus_g_proxy_new_for_name(
 
284
                        bus,
 
285
                        DBUS_SERVICE_ADDRESS,
 
286
                        DBUS_SERVICE_SERVICE_OBJECT,
 
287
                        DBUS_SERVICE_SERVICE_INTERFACE);
 
288
                if (priv->service_proxy == NULL) {
 
289
                        g_warning ("can't setup service_proxy");
 
290
                        return;
 
291
                }
 
292
        }
 
293
 
 
294
        if (priv->accounts_proxy == NULL) {
 
295
                priv->accounts_proxy =
 
296
                        dbus_g_proxy_new_for_name(bus,
 
297
                                                                          DBUS_SERVICE_ADDRESS,
 
298
                                                                          DBUS_SERVICE_ACCOUNTS_OBJECT,
 
299
                                                                          DBUS_SERVICE_ACCOUNTS_INTERFACE);
 
300
                if (priv->accounts_proxy == NULL) {
 
301
                        g_warning ("can't setup accounts_proxy");
 
302
                        return;
 
303
                }
 
304
        }
 
305
 
 
306
        /* Monitor signals about account changes */
 
307
        dbus_g_proxy_add_signal(priv->accounts_proxy, "AccountChanged",
 
308
                                G_TYPE_STRING,
 
309
                                                        G_TYPE_INVALID);
 
310
        dbus_g_proxy_connect_signal(priv->accounts_proxy, "AccountChanged",
 
311
                                G_CALLBACK(accounts_changed),
 
312
                                self, NULL);
 
313
        dbus_g_proxy_add_signal(priv->accounts_proxy, "AccountDeleted",
 
314
                                G_TYPE_STRING,
 
315
                                                        G_TYPE_INVALID);
 
316
        dbus_g_proxy_connect_signal(priv->accounts_proxy, "AccountDeleted",
 
317
                                G_CALLBACK(accounts_changed),
 
318
                                self, NULL);
 
319
 
 
320
}
 
321
 
 
322
static void
 
323
gwibber_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata)
 
324
{
 
325
        if (error) {
 
326
                g_warning ("Unable to check if Gwibber is running: %s", error->message);
 
327
                return;
 
328
        }
 
329
 
 
330
        if (exists) {
 
331
                setup_service_proxies (GWIBBER_SERVICE (userdata));
 
332
                query_account_manager (GWIBBER_SERVICE (userdata));
 
333
        }
 
334
 
 
335
        return;
 
336
}
 
337
 
 
338
GwibberService * gwibber_service_new (void){
 
339
        return GWIBBER_SERVICE (g_object_new (GWIBBER_SERVICE_TYPE, NULL));
 
340
}
 
341
 
 
342
static void
 
343
send_message_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
 
344
{
 
345
        g_debug ("send_message_response");
53
346
 
54
347
        return;
55
348
}
56
349
 
57
350
void
58
 
gwibber_send (const gchar *msg)
 
351
gwibber_service_send (GwibberService *self, const gchar *msg)
59
352
{
60
 
        setup_gwibber_proxy ();
 
353
        g_return_if_fail (IS_GWIBBER_SERVICE (self));
61
354
 
62
 
        if (gwibber_proxy == NULL) {
63
 
                g_warning ("Can not get a gwibber proxy object");
64
 
        }
 
355
        GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
65
356
 
66
357
        GValue value = {0};
67
358
        g_value_init(&value, G_TYPE_STRING);
69
360
 
70
361
        g_debug ("gwibber_send: %s\n", msg);
71
362
 
72
 
        dbus_g_proxy_begin_call(gwibber_proxy,
 
363
        if (priv->service_proxy == NULL) {
 
364
                setup_service_proxies (self);
 
365
                if (priv->service_proxy == NULL) {
 
366
                        g_warning ("can't setup service_proxy");
 
367
                        return;
 
368
                }
 
369
        }
 
370
 
 
371
        dbus_g_proxy_begin_call(priv->service_proxy,
73
372
                                "SendMessage",
74
 
                                gwibber_response,
 
373
                                send_message_response,
75
374
                                NULL,
76
375
                                NULL,
77
376
                                G_TYPE_VALUE,
82
381
 
83
382
        return;
84
383
}
 
384
 
 
385
GwibberService *
 
386
gwibber_service_get (void)
 
387
{
 
388
  static GwibberService *singleton = NULL;
 
389
 
 
390
  if (! singleton) {
 
391
          singleton = gwibber_service_new ();
 
392
  }     
 
393
 
 
394
  return singleton;
 
395
}
 
396
 
 
397
gboolean
 
398
gwibber_service_has_configured_accounts (GwibberService *self)
 
399
{
 
400
        g_return_val_if_fail (IS_GWIBBER_SERVICE (self), FALSE);
 
401
 
 
402
        GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
 
403
 
 
404
        return priv->has_configured_accounts;
 
405
}