]> git.0d.be Git - empathy.git/blobdiff - src/empathy-call-handler.c
Include dbus-reason in signal arguments
[empathy.git] / src / empathy-call-handler.c
index eca076d94b046038dfc8c78bbf95dfcabb3ef23c..99054b9def4b6f8e1fb4d58ec32fe3c55e05796e 100644 (file)
@@ -33,9 +33,9 @@
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-tp-contact-factory.h>
 
+#include <libempathy-gtk/empathy-call-utils.h>
+
 #include "empathy-call-handler.h"
-#include "empathy-call-factory.h"
-#include "src-marshal.h"
 
 #define DEBUG_FLAG EMPATHY_DEBUG_VOIP
 #include <libempathy/empathy-debug.h>
@@ -51,6 +51,7 @@ enum {
   SINK_PAD_REMOVED,
   CLOSED,
   CANDIDATES_CHANGED,
+  STATE_CHANGED,
   LAST_SIGNAL
 };
 
@@ -75,7 +76,7 @@ enum {
 
 /* private structure */
 
-typedef struct {
+struct _EmpathyCallHandlerPriv {
   TpyCallChannel *call;
 
   EmpathyContact *contact;
@@ -93,7 +94,7 @@ typedef struct {
   FsCandidate *video_remote_candidate;
   FsCandidate *audio_local_candidate;
   FsCandidate *video_local_candidate;
-} EmpathyCallHandlerPriv;
+};
 
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyCallHandler)
 
@@ -151,8 +152,6 @@ on_get_contacts_cb (TpConnection *connection,
   EmpathyCallHandlerPriv *priv = GET_PRIV (self);
   guint i;
 
-  g_print ("\nGot %d EmpathyContacts\n\n", n_contacts);
-
   if (n_failed > 0)
     g_warning ("Failed to get %d EmpathyContacts: %s",
         n_failed, error->message);
@@ -168,6 +167,51 @@ on_get_contacts_cb (TpConnection *connection,
   g_object_notify (G_OBJECT (self), "members");
 }
 
+static void
+on_call_invalidated_cb (TpyCallChannel *call,
+    guint domain,
+    gint code,
+    gchar *message,
+    EmpathyCallHandler *self)
+{
+  EmpathyCallHandlerPriv *priv = self->priv;
+
+  if (priv->call == call)
+    {
+      /* Invalidated unexpectedly? Fake call ending */
+      g_signal_emit (self, signals[STATE_CHANGED], 0,
+          TPY_CALL_STATE_ENDED, NULL);
+      tp_clear_object (&priv->call);
+      tp_clear_object (&priv->tfchannel);
+    }
+}
+
+static void
+on_call_state_changed_cb (TpyCallChannel *call,
+  TpyCallState state,
+  TpyCallFlags flags,
+  const GValueArray *call_state_reason,
+  GHashTable *call_state_details,
+  EmpathyCallHandler *handler)
+{
+  EmpathyCallHandlerPriv *priv = handler->priv;
+  gchar *dbus_reason;
+  guint actor, reason;
+
+  tp_value_array_unpack ((GValueArray *) call_state_reason, 3,
+      &actor, &reason, &dbus_reason);
+
+  g_signal_emit (handler, signals[STATE_CHANGED], 0, state, dbus_reason);
+
+  if (state == TPY_CALL_STATE_ENDED)
+    {
+      tp_channel_close_async (TP_CHANNEL (call), NULL, NULL);
+
+      tp_clear_object (&priv->call);
+      tp_clear_object (&priv->tfchannel);
+    }
+}
+
 static void
 on_members_changed_cb (TpyCallChannel *call,
     GHashTable *members,
@@ -180,16 +224,10 @@ on_members_changed_cb (TpyCallChannel *call,
   guint n_handles;
   guint i = 0;
 
-  g_print ("\non_members_changed!\n\n");
-
   if (members == NULL)
-    {
-      g_print ("\nmembers is null!\n\n");
-      return;
-    }
+    return;
 
   n_handles = g_hash_table_size (members);
-  g_print ("\nn_handles: %d\n\n", n_handles);
   if (n_handles == 0)
     return;
 
@@ -241,7 +279,14 @@ empathy_call_handler_set_property (GObject *object,
         priv->members = g_value_get_boxed (value);
         break;
       case PROP_CALL_CHANNEL:
+        g_return_if_fail (priv->call == NULL);
+
         priv->call = g_value_dup_object (value);
+
+        tp_g_signal_connect_object (priv->call, "state-changed",
+          G_CALLBACK (on_call_state_changed_cb), object, 0);
+        tp_g_signal_connect_object (priv->call, "invalidated",
+          G_CALLBACK (on_call_invalidated_cb), object, 0);
         break;
       case PROP_INITIAL_AUDIO:
         priv->initial_audio = g_value_get_boolean (value);
@@ -349,7 +394,7 @@ empathy_call_handler_class_init (EmpathyCallHandlerClass *klass)
   param_spec = g_param_spec_boolean ("initial-video",
     "initial-video", "Whether the call should start with video",
     FALSE,
-    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+    G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
   g_object_class_install_property (object_class, PROP_INITIAL_VIDEO,
     param_spec);
 
@@ -416,50 +461,56 @@ empathy_call_handler_class_init (EmpathyCallHandlerClass *klass)
   signals[CONFERENCE_ADDED] =
     g_signal_new ("conference-added", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      g_cclosure_marshal_VOID__OBJECT,
+      g_cclosure_marshal_generic,
       G_TYPE_NONE,
       1, FS_TYPE_CONFERENCE);
 
   signals[CONFERENCE_REMOVED] =
     g_signal_new ("conference-removed", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      g_cclosure_marshal_VOID__OBJECT,
+      g_cclosure_marshal_generic,
       G_TYPE_NONE,
       1, FS_TYPE_CONFERENCE);
 
   signals[SRC_PAD_ADDED] =
     g_signal_new ("src-pad-added", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      _src_marshal_BOOLEAN__OBJECT_UINT,
+      g_cclosure_marshal_generic,
       G_TYPE_BOOLEAN,
       2, GST_TYPE_PAD, G_TYPE_UINT);
 
   signals[SINK_PAD_ADDED] =
     g_signal_new ("sink-pad-added", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      _src_marshal_BOOLEAN__OBJECT_UINT,
+      g_cclosure_marshal_generic,
       G_TYPE_BOOLEAN,
       2, GST_TYPE_PAD, G_TYPE_UINT);
 
   signals[SINK_PAD_REMOVED] =
     g_signal_new ("sink-pad-removed", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      _src_marshal_BOOLEAN__OBJECT_UINT,
+      g_cclosure_marshal_generic,
       G_TYPE_BOOLEAN,
       2, GST_TYPE_PAD, G_TYPE_UINT);
 
   signals[CLOSED] =
     g_signal_new ("closed", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      g_cclosure_marshal_VOID__VOID,
+      g_cclosure_marshal_generic,
       G_TYPE_NONE,
       0);
 
   signals[CANDIDATES_CHANGED] =
     g_signal_new ("candidates-changed", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      g_cclosure_marshal_VOID__UINT,
+      g_cclosure_marshal_generic,
       G_TYPE_NONE, 1, G_TYPE_UINT);
+
+  signals[STATE_CHANGED] =
+    g_signal_new ("state-changed", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+      g_cclosure_marshal_generic,
+      G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING);
 }
 
 EmpathyCallHandler *
@@ -608,7 +659,7 @@ empathy_call_handler_bus_message (EmpathyCallHandler *handler,
       FsCodec *codec;
       FsSession *session;
 
-      g_print ("empathy_call_handler_bus_message: farsight-send-codec-changed\n");
+      DEBUG ("farsight-send-codec-changed");
 
       val = gst_structure_get_value (s, "codec");
       codec = g_value_get_boxed (val);
@@ -625,7 +676,7 @@ empathy_call_handler_bus_message (EmpathyCallHandler *handler,
       GList *codecs;
       FsStream *stream;
 
-      g_print ("empathy_call_handler_bus_message: farsight-recv-codecs-changed\n");
+      DEBUG ("farsight-recv-codecs-changed");
 
       val = gst_structure_get_value (s, "codecs");
       codecs = g_value_get_boxed (val);
@@ -642,7 +693,7 @@ empathy_call_handler_bus_message (EmpathyCallHandler *handler,
       FsCandidate *remote_candidate, *local_candidate;
       FsStream *stream;
 
-      g_print ("empathy_call_handler_bus_message: farsight-new-active-candidate-pair\n");
+      DEBUG ("farsight-new-active-candidate-pair");
 
       val = gst_structure_get_value (s, "remote-candidate");
       remote_candidate = g_value_get_boxed (val);
@@ -773,7 +824,7 @@ on_tf_channel_content_removed_cb (TfChannel *tfchannel,
   GstPad *spad;
   gboolean retval;
 
-  g_print ("removing content\n");
+  DEBUG ("removing content");
 
   g_object_get (content, "media-type", &mtype,
     "sink-pad", &spad, NULL);
@@ -838,7 +889,21 @@ empathy_call_handler_start_tpfs (EmpathyCallHandler *self)
       on_tf_channel_ready, self);
 }
 
-#if 0
+static void
+on_call_accepted_cb (GObject *source_object,
+    GAsyncResult *res,
+    gpointer user_data)
+{
+  TpyCallChannel *call = TPY_CALL_CHANNEL (source_object);
+  GError *error = NULL;
+
+  if (!tpy_call_channel_accept_finish (call, res, &error))
+    {
+      g_warning ("could not accept Call: %s", error->message);
+      g_error_free (error);
+    }
+}
+
 static void
 empathy_call_handler_request_cb (GObject *source,
     GAsyncResult *result,
@@ -866,26 +931,15 @@ empathy_call_handler_request_cb (GObject *source,
     }
 
   priv->call = TPY_CALL_CHANNEL (channel);
+  tp_g_signal_connect_object (priv->call, "state-changed",
+    G_CALLBACK (on_call_state_changed_cb), self, 0);
+  tp_g_signal_connect_object (priv->call, "invalidated",
+    G_CALLBACK (on_call_invalidated_cb), self, 0);
 
   g_object_notify (G_OBJECT (self), "call-channel");
 
   empathy_call_handler_start_tpfs (self);
-}
-#endif
-
-static void
-on_call_accepted_cb (GObject *source_object,
-    GAsyncResult *res,
-    gpointer user_data)
-{
-  TpyCallChannel *call = TPY_CALL_CHANNEL (source_object);
-  GError *error = NULL;
-
-  if (!tpy_call_channel_accept_finish (call, res, &error))
-    {
-      g_warning ("could not accept Call: %s", error->message);
-      g_error_free (error);
-    }
+  tpy_call_channel_accept_async (priv->call, on_call_accepted_cb, NULL);
 }
 
 void
@@ -893,9 +947,9 @@ empathy_call_handler_start_call (EmpathyCallHandler *handler,
     gint64 timestamp)
 {
   EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
-/*TpAccountChannelRequest *req;
+  TpAccountChannelRequest *req;
   TpAccount *account;
-  GHashTable *request;*/
+  GHashTable *request;
 
   if (priv->call != NULL)
     {
@@ -903,17 +957,13 @@ empathy_call_handler_start_call (EmpathyCallHandler *handler,
       tpy_call_channel_accept_async (priv->call, on_call_accepted_cb, NULL);
       return;
     }
-  else
-    {
-      g_warning ("No Call channel!");
-    }
 
-#if 0
   /* No TpyCallChannel (we are redialing). Request a new call channel */
   g_assert (priv->contact != NULL);
 
   account = empathy_contact_get_account (priv->contact);
-  request = empathy_call_create_call_request (priv->contact,
+  request = empathy_call_create_call_request (
+      empathy_contact_get_id (priv->contact),
       priv->initial_audio, priv->initial_video);
 
   req = tp_account_channel_request_new (account, request, timestamp);
@@ -923,7 +973,6 @@ empathy_call_handler_start_call (EmpathyCallHandler *handler,
 
   g_object_unref (req);
   g_hash_table_unref (request);
-#endif
 }
 
 /**