]> git.0d.be Git - empathy.git/blob - ubuntu-online-accounts/mc-plugin/empathy-webcredentials-monitor.c
439bbda65c324712861e786fb597f936c8d492ef
[empathy.git] / ubuntu-online-accounts / mc-plugin / empathy-webcredentials-monitor.c
1 #include "config.h"
2
3 #include <gio/gio.h>
4
5 #include <telepathy-glib/telepathy-glib.h>
6
7 #include <libaccounts-glib/ag-account.h>
8
9 #include "empathy-webcredentials-monitor.h"
10
11 G_DEFINE_TYPE (EmpathyWebcredentialsMonitor, empathy_webcredentials_monitor, G_TYPE_OBJECT)
12
13 #define WEBCRED_BUS_NAME "com.canonical.indicators.webcredentials"
14 #define WEBCRED_PATH "/com/canonical/indicators/webcredentials"
15 #define WEBCRED_IFACE "com.canonical.indicators.webcredentials"
16
17 #define FAILURES_PROP "Failures"
18
19 enum
20 {
21   PROP_MANAGER = 1,
22   N_PROPS
23 };
24
25 enum
26 {
27   SIG_FAILURE_ADDED,
28   SIG_FAILURE_REMOVED,
29   LAST_SIGNAL
30 };
31
32 static guint signals[LAST_SIGNAL];
33
34 struct _EmpathyWebcredentialsMonitorPriv
35 {
36   AgManager *manager;
37   GDBusProxy *proxy;
38
39   /* array of owned AgAccount */
40   GPtrArray *failures;
41 };
42
43 static void
44 empathy_webcredentials_monitor_get_property (GObject *object,
45     guint property_id,
46     GValue *value,
47     GParamSpec *pspec)
48 {
49   EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object);
50
51   switch (property_id)
52     {
53       case PROP_MANAGER:
54         g_value_set_object (value, self->priv->manager);
55         break;
56       default:
57         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
58         break;
59     }
60 }
61
62 static void
63 empathy_webcredentials_monitor_set_property (GObject *object,
64     guint property_id,
65     const GValue *value,
66     GParamSpec *pspec)
67 {
68   EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object);
69
70   switch (property_id)
71     {
72       case PROP_MANAGER:
73         g_assert (self->priv->manager == NULL); /* construct only */
74         self->priv->manager = g_value_dup_object (value);
75         break;
76       default:
77         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
78         break;
79     }
80 }
81
82 static void
83 empathy_webcredentials_monitor_constructed (GObject *object)
84 {
85   EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object);
86   void (*chain_up) (GObject *) =
87       ((GObjectClass *) empathy_webcredentials_monitor_parent_class)->constructed;
88
89   chain_up (object);
90
91   g_assert (AG_IS_MANAGER (self->priv->manager));
92 }
93
94 static void
95 empathy_webcredentials_monitor_dispose (GObject *object)
96 {
97   EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object);
98   void (*chain_up) (GObject *) =
99       ((GObjectClass *) empathy_webcredentials_monitor_parent_class)->dispose;
100
101   g_clear_object (&self->priv->manager);
102   g_clear_object (&self->priv->proxy);
103
104   chain_up (object);
105 }
106
107 static void
108 empathy_webcredentials_monitor_finalize (GObject *object)
109 {
110   EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object);
111   void (*chain_up) (GObject *) =
112       ((GObjectClass *) empathy_webcredentials_monitor_parent_class)->finalize;
113
114   g_ptr_array_unref (self->priv->failures);
115
116   chain_up (object);
117 }
118
119 static void
120 empathy_webcredentials_monitor_class_init (
121     EmpathyWebcredentialsMonitorClass *klass)
122 {
123   GObjectClass *oclass = G_OBJECT_CLASS (klass);
124   GParamSpec *spec;
125
126   oclass->get_property = empathy_webcredentials_monitor_get_property;
127   oclass->set_property = empathy_webcredentials_monitor_set_property;
128   oclass->constructed = empathy_webcredentials_monitor_constructed;
129   oclass->dispose = empathy_webcredentials_monitor_dispose;
130   oclass->finalize = empathy_webcredentials_monitor_finalize;
131
132   spec = g_param_spec_object ("manager", "Manager",
133       "AgManager",
134       AG_TYPE_MANAGER,
135       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
136   g_object_class_install_property (oclass, PROP_MANAGER, spec);
137
138   signals[SIG_FAILURE_ADDED] = g_signal_new ("failure-added",
139       G_OBJECT_CLASS_TYPE (klass),
140       G_SIGNAL_RUN_LAST,
141       0, NULL, NULL, NULL,
142       G_TYPE_NONE,
143       1, AG_TYPE_ACCOUNT);
144
145   signals[SIG_FAILURE_REMOVED] = g_signal_new ("failure-removed",
146       G_OBJECT_CLASS_TYPE (klass),
147       G_SIGNAL_RUN_LAST,
148       0, NULL, NULL, NULL,
149       G_TYPE_NONE,
150       1, AG_TYPE_ACCOUNT);
151
152   g_type_class_add_private (klass, sizeof (EmpathyWebcredentialsMonitorPriv));
153 }
154
155 static void
156 update_failures (EmpathyWebcredentialsMonitor *self)
157 {
158   GVariant *failures, *f;
159   GVariantIter iter;
160   GList *new_list = NULL;
161   guint i;
162
163   failures = g_dbus_proxy_get_cached_property (self->priv->proxy,
164       FAILURES_PROP);
165   if (failures == NULL)
166     {
167       g_debug ("Does not implement Failures property");
168       return;
169     }
170
171   g_variant_iter_init (&iter, failures);
172   while ((f = g_variant_iter_next_value (&iter)) != NULL)
173     {
174       guint32 id;
175       AgAccount *account;
176
177       id = g_variant_get_uint32 (f);
178
179       account = ag_manager_get_account (self->priv->manager, id);
180       if (account == NULL)
181         continue;
182
183       /* Pass ownership of 'account' to the list */
184       new_list = g_list_append (new_list, account);
185
186       if (!tp_g_ptr_array_contains (self->priv->failures, account))
187         {
188           g_ptr_array_add (self->priv->failures, g_object_ref (account));
189
190           g_signal_emit (self, signals[SIG_FAILURE_ADDED], 0, account);
191         }
192
193       g_variant_unref (f);
194     }
195
196   g_variant_unref (failures);
197
198   for (i = 0; i < self->priv->failures->len; i++)
199     {
200       AgAccount *account = g_ptr_array_index (self->priv->failures, i);
201
202       if (g_list_find (new_list, account) == NULL)
203         {
204           g_object_ref (account);
205           g_ptr_array_remove (self->priv->failures, account);
206
207           g_signal_emit (self, signals[SIG_FAILURE_REMOVED], 0, account);
208           g_object_unref (account);
209         }
210     }
211
212   g_list_free_full (new_list, g_object_unref);
213 }
214
215 static void
216 properties_changed_cb (GDBusProxy *proxy,
217     GVariant *changed_properties,
218     GStrv invalidated_properties,
219     EmpathyWebcredentialsMonitor *self)
220 {
221   if (g_variant_lookup_value (changed_properties, FAILURES_PROP, NULL) == NULL)
222     return;
223
224   update_failures (self);
225 }
226
227 static void
228 proxy_new_cb (GObject *source,
229     GAsyncResult *result,
230     gpointer user_data)
231 {
232   EmpathyWebcredentialsMonitor *self;
233   TpWeakRef *wr = user_data;
234   GError *error = NULL;
235
236   self = tp_weak_ref_dup_object (wr);
237   if (self == NULL)
238     goto out;
239
240   self->priv->proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
241   if (self->priv->proxy == NULL)
242     {
243       g_debug ("Failed to create webcredentials proxy: %s", error->message);
244       g_error_free (error);
245       goto out;
246     }
247
248   update_failures (self);
249
250   g_signal_connect (self->priv->proxy, "g-properties-changed",
251       G_CALLBACK (properties_changed_cb), self);
252
253 out:
254   tp_weak_ref_destroy (wr);
255   g_clear_object (&self);
256 }
257
258 static void
259 empathy_webcredentials_monitor_init (EmpathyWebcredentialsMonitor *self)
260 {
261   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
262       EMPATHY_TYPE_WEBCREDENTIALS_MONITOR, EmpathyWebcredentialsMonitorPriv);
263
264   self->priv->failures = g_ptr_array_new_with_free_func (g_object_unref);
265
266   g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL,
267       WEBCRED_BUS_NAME, WEBCRED_PATH, WEBCRED_IFACE,
268       NULL, proxy_new_cb, tp_weak_ref_new (self, NULL, NULL));
269 }
270
271 EmpathyWebcredentialsMonitor *
272 empathy_webcredentials_monitor_new (AgManager *manager)
273 {
274   return g_object_new (EMPATHY_TYPE_WEBCREDENTIALS_MONITOR,
275       "manager", manager,
276       NULL);
277 }
278
279 GPtrArray *
280 empathy_webcredentials_get_failures (EmpathyWebcredentialsMonitor *self)
281 {
282   return self->priv->failures;
283 }