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