dispatcher: remove more unused attributes and code
[empathy-mirror.git] / libempathy / empathy-dispatch-operation.c
blobadb76c77c03fa0a42dce0bfaf7eb37e2a57d061f
1 /*
2 * empathy-dispatch-operation.c - Source for EmpathyDispatchOperation
3 * Copyright (C) 2008 Collabora Ltd.
4 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <stdio.h>
23 #include <stdlib.h>
25 #include <telepathy-glib/interfaces.h>
27 #include "empathy-dispatch-operation.h"
28 #include <libempathy/empathy-enum-types.h>
29 #include <libempathy/empathy-tp-contact-factory.h>
31 #include "empathy-marshal.h"
33 #include "extensions/extensions.h"
35 #define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER
36 #include <libempathy/empathy-debug.h>
38 G_DEFINE_TYPE(EmpathyDispatchOperation, empathy_dispatch_operation,
39 G_TYPE_OBJECT)
41 static void empathy_dispatch_operation_set_status (
42 EmpathyDispatchOperation *self, EmpathyDispatchOperationState status);
43 static void empathy_dispatch_operation_channel_ready_cb (TpChannel *channel,
44 const GError *error, gpointer user_data);
46 /* signal enum */
47 enum
49 /* Ready for dispatching */
50 READY,
51 /* Claimed by a handler */
52 CLAIMED,
53 /* Error, channel went away, inspecting it failed etc */
54 INVALIDATED,
55 LAST_SIGNAL
58 static guint signals[LAST_SIGNAL] = {0};
60 /* properties */
61 enum {
62 PROP_CONNECTION = 1,
63 PROP_CHANNEL,
64 PROP_CHANNEL_WRAPPER,
65 PROP_CONTACT,
66 PROP_INCOMING,
67 PROP_STATUS,
68 PROP_USER_ACTION_TIME,
71 /* private structure */
72 typedef struct _EmpathyDispatchOperationPriv \
73 EmpathyDispatchOperationPriv;
75 struct _EmpathyDispatchOperationPriv
77 gboolean dispose_has_run;
78 TpConnection *connection;
79 TpChannel *channel;
80 GObject *channel_wrapper;
81 EmpathyContact *contact;
82 EmpathyDispatchOperationState status;
83 gboolean incoming;
84 gint64 user_action_time;
85 gulong invalidated_handler;
86 gulong ready_handler;
89 #define GET_PRIV(o) \
90 (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_DISPATCH_OPERATION, \
91 EmpathyDispatchOperationPriv))
93 static void
94 empathy_dispatch_operation_init (EmpathyDispatchOperation *obj)
96 //EmpathyDispatchOperationPriv *priv =
97 // GET_PRIV (obj);
99 /* allocate any data required by the object here */
102 static void empathy_dispatch_operation_dispose (GObject *object);
103 static void empathy_dispatch_operation_finalize (GObject *object);
105 static void
106 empathy_dispatch_operation_set_property (GObject *object,
107 guint property_id, const GValue *value, GParamSpec *pspec)
109 EmpathyDispatchOperation *operation = EMPATHY_DISPATCH_OPERATION (object);
110 EmpathyDispatchOperationPriv *priv = GET_PRIV (operation);
112 switch (property_id)
114 case PROP_CONNECTION:
115 priv->connection = g_value_dup_object (value);
116 break;
117 case PROP_CHANNEL:
118 priv->channel = g_value_dup_object (value);
119 break;
120 case PROP_CHANNEL_WRAPPER:
121 priv->channel_wrapper = g_value_dup_object (value);
122 break;
123 case PROP_CONTACT:
124 if (priv->contact != NULL)
125 g_object_unref (priv->contact);
126 priv->contact = g_value_dup_object (value);
127 break;
128 case PROP_INCOMING:
129 priv->incoming = g_value_get_boolean (value);
130 break;
131 case PROP_USER_ACTION_TIME:
132 priv->user_action_time = g_value_get_int64 (value);
133 break;
134 default:
135 g_assert_not_reached ();
139 static void
140 empathy_dispatch_operation_get_property (GObject *object,
141 guint property_id, GValue *value, GParamSpec *pspec)
143 EmpathyDispatchOperation *operation = EMPATHY_DISPATCH_OPERATION (object);
144 EmpathyDispatchOperationPriv *priv = GET_PRIV (operation);
146 switch (property_id)
148 case PROP_CONNECTION:
149 g_value_set_object (value, priv->connection);
150 break;
151 case PROP_CHANNEL:
152 g_value_set_object (value, priv->channel);
153 break;
154 case PROP_CHANNEL_WRAPPER:
155 g_value_set_object (value, priv->channel_wrapper);
156 break;
157 case PROP_CONTACT:
158 g_value_set_object (value, priv->contact);
159 break;
160 case PROP_INCOMING:
161 g_value_set_boolean (value, priv->incoming);
162 break;
163 case PROP_STATUS:
164 g_value_set_enum (value, priv->status);
165 break;
166 case PROP_USER_ACTION_TIME:
167 g_value_set_int64 (value, priv->user_action_time);
168 break;
169 default:
170 g_assert_not_reached ();
174 static void
175 empathy_dispatch_operation_invalidated (TpProxy *proxy, guint domain,
176 gint code, char *message, EmpathyDispatchOperation *self)
178 empathy_dispatch_operation_set_status (self,
179 EMPATHY_DISPATCHER_OPERATION_STATE_INVALIDATED);
181 g_signal_emit (self, signals[INVALIDATED], 0, domain, code, message);
184 static void
185 dispatcher_operation_got_contact_cb (TpConnection *connection,
186 EmpathyContact *contact,
187 const GError *error,
188 gpointer user_data,
189 GObject *self)
191 EmpathyDispatchOperationPriv *priv = GET_PRIV (self);
193 if (error)
195 /* FIXME: We should cancel the operation */
196 DEBUG ("Error: %s", error->message);
197 return;
200 if (priv->contact != NULL)
201 g_object_unref (priv->contact);
202 priv->contact = g_object_ref (contact);
203 g_object_notify (G_OBJECT (self), "contact");
205 /* Ensure to keep the self object alive while the call_when_ready is
206 * running */
207 g_object_ref (self);
208 tp_channel_call_when_ready (priv->channel,
209 empathy_dispatch_operation_channel_ready_cb, self);
212 static void
213 dispatch_operation_connection_ready (TpConnection *connection,
214 const GError *error,
215 gpointer user_data)
217 EmpathyDispatchOperation *self = EMPATHY_DISPATCH_OPERATION (user_data);
218 EmpathyDispatchOperationPriv *priv = GET_PRIV (self);
219 TpHandle handle;
220 TpHandleType handle_type;
222 if (error != NULL)
223 goto out;
225 if (priv->status >= EMPATHY_DISPATCHER_OPERATION_STATE_CLAIMED)
226 /* no point to get more information */
227 goto out;
229 handle = tp_channel_get_handle (priv->channel, &handle_type);
230 if (handle_type == TP_HANDLE_TYPE_CONTACT && priv->contact == NULL)
232 empathy_tp_contact_factory_get_from_handle (priv->connection, handle,
233 dispatcher_operation_got_contact_cb, NULL, NULL, G_OBJECT (self));
235 else
237 g_object_ref (self);
238 tp_channel_call_when_ready (priv->channel,
239 empathy_dispatch_operation_channel_ready_cb, self);
242 out:
243 g_object_unref (self);
246 static void
247 empathy_dispatch_operation_constructed (GObject *object)
249 EmpathyDispatchOperation *self = EMPATHY_DISPATCH_OPERATION (object);
250 EmpathyDispatchOperationPriv *priv = GET_PRIV (self);
252 empathy_dispatch_operation_set_status (self,
253 EMPATHY_DISPATCHER_OPERATION_STATE_PREPARING);
255 priv->invalidated_handler =
256 g_signal_connect (priv->channel, "invalidated",
257 G_CALLBACK (empathy_dispatch_operation_invalidated), self);
259 g_object_ref (self);
260 tp_connection_call_when_ready (priv->connection,
261 dispatch_operation_connection_ready, object);
264 static void
265 empathy_dispatch_operation_class_init (
266 EmpathyDispatchOperationClass *empathy_dispatch_operation_class)
268 GObjectClass *object_class =
269 G_OBJECT_CLASS (empathy_dispatch_operation_class);
270 GParamSpec *param_spec;
272 g_type_class_add_private (empathy_dispatch_operation_class,
273 sizeof (EmpathyDispatchOperationPriv));
275 object_class->set_property = empathy_dispatch_operation_set_property;
276 object_class->get_property = empathy_dispatch_operation_get_property;
278 object_class->dispose = empathy_dispatch_operation_dispose;
279 object_class->finalize = empathy_dispatch_operation_finalize;
280 object_class->constructed = empathy_dispatch_operation_constructed;
282 signals[READY] = g_signal_new ("ready",
283 G_OBJECT_CLASS_TYPE(empathy_dispatch_operation_class),
284 G_SIGNAL_RUN_LAST,
286 NULL, NULL,
287 g_cclosure_marshal_VOID__VOID,
288 G_TYPE_NONE, 0);
290 signals[CLAIMED] = g_signal_new ("claimed",
291 G_OBJECT_CLASS_TYPE(empathy_dispatch_operation_class),
292 G_SIGNAL_RUN_LAST,
294 NULL, NULL,
295 g_cclosure_marshal_VOID__VOID,
296 G_TYPE_NONE, 0);
298 signals[INVALIDATED] = g_signal_new ("invalidated",
299 G_OBJECT_CLASS_TYPE(empathy_dispatch_operation_class),
300 G_SIGNAL_RUN_LAST,
302 NULL, NULL,
303 _empathy_marshal_VOID__UINT_INT_STRING,
304 G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_INT, G_TYPE_STRING);
306 param_spec = g_param_spec_object ("connection",
307 "connection", "The telepathy connection",
308 TP_TYPE_CONNECTION,
309 G_PARAM_CONSTRUCT_ONLY |
310 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
311 g_object_class_install_property (object_class, PROP_CONNECTION,
312 param_spec);
314 param_spec = g_param_spec_object ("channel",
315 "channel", "The telepathy channel",
316 TP_TYPE_CHANNEL,
317 G_PARAM_CONSTRUCT_ONLY |
318 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
319 g_object_class_install_property (object_class, PROP_CHANNEL,
320 param_spec);
322 param_spec = g_param_spec_object ("channel-wrapper",
323 "channel wrapper", "The empathy specific channel wrapper",
324 G_TYPE_OBJECT,
325 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
326 g_object_class_install_property (object_class, PROP_CHANNEL_WRAPPER,
327 param_spec);
329 param_spec = g_param_spec_object ("contact",
330 "contact", "The empathy contact",
331 EMPATHY_TYPE_CONTACT,
332 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
333 g_object_class_install_property (object_class, PROP_CONTACT,
334 param_spec);
336 param_spec = g_param_spec_boolean ("incoming",
337 "incoming", "Whether or not the channel is incoming",
338 FALSE,
339 G_PARAM_CONSTRUCT_ONLY |
340 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
341 g_object_class_install_property (object_class, PROP_INCOMING,
342 param_spec);
344 param_spec = g_param_spec_enum ("status",
345 "status", "Status of the dispatch operation",
346 EMPATHY_TYPE_DISPATCH_OPERATION_STATE, 0,
347 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
348 g_object_class_install_property (object_class, PROP_STATUS, param_spec);
350 param_spec = g_param_spec_int64 ("user-action-time",
351 "user action time", "The user action time of the operation",
352 G_MININT64, G_MAXINT64, 0,
353 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
354 g_object_class_install_property (object_class, PROP_USER_ACTION_TIME,
355 param_spec);
358 void
359 empathy_dispatch_operation_dispose (GObject *object)
361 EmpathyDispatchOperation *self = EMPATHY_DISPATCH_OPERATION (object);
362 EmpathyDispatchOperationPriv *priv =
363 GET_PRIV (self);
365 if (priv->dispose_has_run)
366 return;
368 priv->dispose_has_run = TRUE;
370 g_object_unref (priv->connection);
372 if (priv->ready_handler != 0)
373 g_signal_handler_disconnect (priv->channel_wrapper,
374 priv->ready_handler);
376 if (priv->channel_wrapper != NULL)
377 g_object_unref (priv->channel_wrapper);
379 g_signal_handler_disconnect (priv->channel, priv->invalidated_handler);
380 g_object_unref (priv->channel);
382 if (priv->contact != NULL)
383 g_object_unref (priv->contact);
385 if (G_OBJECT_CLASS (empathy_dispatch_operation_parent_class)->dispose)
386 G_OBJECT_CLASS (empathy_dispatch_operation_parent_class)->dispose (object);
389 void
390 empathy_dispatch_operation_finalize (GObject *object)
392 /* free any data held directly by the object here */
393 G_OBJECT_CLASS (empathy_dispatch_operation_parent_class)->finalize (object);
396 static void
397 empathy_dispatch_operation_set_status (EmpathyDispatchOperation *self,
398 EmpathyDispatchOperationState status)
400 EmpathyDispatchOperationPriv *priv = GET_PRIV (self);
402 g_assert (status >= priv->status);
405 if (priv->status != status)
407 DEBUG ("Dispatch operation %s status: %d -> %d",
408 empathy_dispatch_operation_get_object_path (self),
409 priv->status, status);
411 priv->status = status;
412 g_object_notify (G_OBJECT (self), "status");
414 if (status == EMPATHY_DISPATCHER_OPERATION_STATE_PENDING)
415 g_signal_emit (self, signals[READY], 0);
419 static void
420 empathy_dispatch_operation_channel_ready_cb (TpChannel *channel,
421 const GError *error, gpointer user_data)
423 EmpathyDispatchOperation *self = EMPATHY_DISPATCH_OPERATION (user_data);
424 EmpathyDispatchOperationPriv *priv = GET_PRIV (self);
426 /* FIXME: remove */
428 /* The error will be handled in empathy_dispatch_operation_invalidated */
429 if (error != NULL)
430 goto out;
432 g_assert (channel == priv->channel);
434 if (priv->status >= EMPATHY_DISPATCHER_OPERATION_STATE_CLAIMED)
435 /* no point to get more information */
436 goto out;
438 /* If the channel wrapper is defined, we assume it's ready */
439 if (priv->channel_wrapper != NULL)
440 goto ready;
442 ready:
443 empathy_dispatch_operation_set_status (self,
444 EMPATHY_DISPATCHER_OPERATION_STATE_PENDING);
445 out:
446 g_object_unref (self);
449 EmpathyDispatchOperation *
450 empathy_dispatch_operation_new (TpConnection *connection,
451 TpChannel *channel,
452 EmpathyContact *contact,
453 gboolean incoming,
454 gint64 user_action_time)
456 g_return_val_if_fail (connection != NULL, NULL);
457 g_return_val_if_fail (channel != NULL, NULL);
459 return g_object_new (EMPATHY_TYPE_DISPATCH_OPERATION,
460 "connection", connection,
461 "channel", channel,
462 "contact", contact,
463 "incoming", incoming,
464 "user-action-time", user_action_time,
465 NULL);
468 void
469 empathy_dispatch_operation_start (EmpathyDispatchOperation *operation)
471 EmpathyDispatchOperationPriv *priv;
473 g_return_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation));
475 priv = GET_PRIV (operation);
477 g_return_if_fail (
478 priv->status == EMPATHY_DISPATCHER_OPERATION_STATE_PENDING);
480 empathy_dispatch_operation_set_status (operation,
481 EMPATHY_DISPATCHER_OPERATION_STATE_DISPATCHING);
484 /* Returns whether or not the operation was successfully claimed */
485 gboolean
486 empathy_dispatch_operation_claim (EmpathyDispatchOperation *operation)
488 EmpathyDispatchOperationPriv *priv;
490 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation), FALSE);
492 priv = GET_PRIV (operation);
494 if (priv->status == EMPATHY_DISPATCHER_OPERATION_STATE_CLAIMED)
495 return FALSE;
497 empathy_dispatch_operation_set_status (operation,
498 EMPATHY_DISPATCHER_OPERATION_STATE_CLAIMED);
500 g_signal_emit (operation, signals[CLAIMED], 0);
502 return TRUE;
505 TpConnection *
506 empathy_dispatch_operation_get_tp_connection (
507 EmpathyDispatchOperation *operation)
509 EmpathyDispatchOperationPriv *priv;
511 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation), NULL);
513 priv = GET_PRIV (operation);
515 return priv->connection;
518 TpChannel *
519 empathy_dispatch_operation_get_channel (EmpathyDispatchOperation *operation)
521 EmpathyDispatchOperationPriv *priv;
523 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation), NULL);
525 priv = GET_PRIV (operation);
527 return priv->channel;
530 GObject *
531 empathy_dispatch_operation_get_channel_wrapper (
532 EmpathyDispatchOperation *operation)
534 EmpathyDispatchOperationPriv *priv;
536 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation), NULL);
538 priv = GET_PRIV (operation);
540 return priv->channel_wrapper;
543 const gchar *
544 empathy_dispatch_operation_get_channel_type (
545 EmpathyDispatchOperation *operation)
547 EmpathyDispatchOperationPriv *priv;
549 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation), NULL);
551 priv = GET_PRIV (operation);
553 return tp_channel_get_channel_type (priv->channel);
556 GQuark
557 empathy_dispatch_operation_get_channel_type_id (
558 EmpathyDispatchOperation *operation)
560 EmpathyDispatchOperationPriv *priv;
562 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation), 0);
564 priv = GET_PRIV (operation);
566 return tp_channel_get_channel_type_id (priv->channel);
569 const gchar *
570 empathy_dispatch_operation_get_object_path (
571 EmpathyDispatchOperation *operation)
573 EmpathyDispatchOperationPriv *priv;
575 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation), NULL);
577 priv = GET_PRIV (operation);
579 return tp_proxy_get_object_path (TP_PROXY (priv->channel));
582 EmpathyDispatchOperationState
583 empathy_dispatch_operation_get_status (EmpathyDispatchOperation *operation)
585 EmpathyDispatchOperationPriv *priv;
587 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation),
588 EMPATHY_DISPATCHER_OPERATION_STATE_PREPARING);
590 priv = GET_PRIV (operation);
592 return priv->status;
595 gboolean
596 empathy_dispatch_operation_is_incoming (EmpathyDispatchOperation *operation)
598 EmpathyDispatchOperationPriv *priv;
600 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation), FALSE);
602 priv = GET_PRIV (operation);
604 return priv->incoming;
607 void
608 empathy_dispatch_operation_set_user_action_time (
609 EmpathyDispatchOperation *self,
610 gint64 user_action_time)
612 EmpathyDispatchOperationPriv *priv = GET_PRIV (self);
614 priv->user_action_time = user_action_time;
617 gint64
618 empathy_dispatch_operation_get_user_action_time (EmpathyDispatchOperation *self)
620 EmpathyDispatchOperationPriv *priv;
622 g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (self), FALSE);
624 priv = GET_PRIV (self);
626 return priv->user_action_time;